Просмотр исходного кода

feat: 1v1通话悬浮窗改为应用内(移除全局悬浮窗)

DoggyZhang 1 год назад
Родитель
Сommit
c2c5ed041e
46 измененных файлов с 511 добавлено и 542 удалено
  1. 1 0
      app/src/main/java/com/adealink/weparty/commonui/widget/floatview/BaseWindowManager.kt
  2. 9 0
      app/src/main/java/com/adealink/weparty/commonui/widget/floatview/ModeWindowManagerProxy.kt
  3. 4 0
      app/src/main/java/com/adealink/weparty/commonui/widget/floatview/mode/ActivityModeWindowManager.kt
  4. 4 0
      app/src/main/java/com/adealink/weparty/commonui/widget/floatview/mode/ApplicationModeWindowManager.kt
  5. 4 0
      app/src/main/java/com/adealink/weparty/commonui/widget/floatview/mode/SystemModeWindowManager.kt
  6. 4 0
      app/src/main/java/com/adealink/weparty/commonui/widget/floatview/mode/fix/Android10FixApplicationModeWindowManager.kt
  7. 4 2
      app/src/main/java/com/adealink/weparty/commonui/widget/floatview/view/BaseDragFloatView.kt
  8. 8 0
      app/src/main/java/com/adealink/weparty/module/call/CallModule.kt
  9. 2 0
      app/src/main/java/com/adealink/weparty/module/call/ICallService.kt
  10. 2 0
      app/src/main/java/com/adealink/weparty/widget/floatview/FloatViewFactory.kt
  11. 1 6
      module/call/src/main/AndroidManifest.xml
  12. 3 17
      module/call/src/main/java/com/adealink/weparty/call/CallActivity.kt
  13. 8 2
      module/call/src/main/java/com/adealink/weparty/call/CallServiceImpl.kt
  14. 137 77
      module/call/src/main/java/com/adealink/weparty/call/WenextUICallKitImpl.kt
  15. 2 2
      module/call/src/main/java/com/adealink/weparty/call/chat/comp/ChatRoomTopComp.kt
  16. 4 12
      module/call/src/main/java/com/adealink/weparty/call/chat/fragment/ChatWaitingFragment.kt
  17. 0 11
      module/call/src/main/java/com/adealink/weparty/call/comp/CallGiftComp.kt
  18. 1 0
      module/call/src/main/java/com/adealink/weparty/call/constant/Tags.kt
  19. 0 5
      module/call/src/main/java/com/adealink/weparty/call/interceptor/EnterCallUriInterceptor.kt
  20. 7 1
      module/call/src/main/java/com/adealink/weparty/call/manager/CallManager.kt
  21. 5 0
      module/call/src/main/java/com/adealink/weparty/call/manager/ICallManager.kt
  22. 0 3
      module/call/src/main/java/com/adealink/weparty/call/video/comp/VideoCallerComp.kt
  23. 0 2
      module/call/src/main/java/com/adealink/weparty/call/video/comp/VideoRoomComp.kt
  24. 2 2
      module/call/src/main/java/com/adealink/weparty/call/video/comp/VideoRoomTopComp.kt
  25. 2 2
      module/call/src/main/java/com/adealink/weparty/call/video/fragment/VideoCalledFragment.kt
  26. 2 2
      module/call/src/main/java/com/adealink/weparty/call/video/fragment/VideoCallerFragment.kt
  27. 10 0
      module/call/src/main/java/com/adealink/weparty/call/view/floatview/calling/CallingFloatData.kt
  28. 132 0
      module/call/src/main/java/com/adealink/weparty/call/view/floatview/calling/CallingFloatView.kt
  29. 47 23
      module/call/src/main/java/com/adealink/weparty/call/view/floatview/calling/CallingView.kt
  30. 7 0
      module/call/src/main/java/com/adealink/weparty/call/view/floatview/calling/ICalling.kt
  31. 1 1
      module/call/src/main/java/com/adealink/weparty/call/view/floatview/incoming/IInComing.kt
  32. 1 1
      module/call/src/main/java/com/adealink/weparty/call/view/floatview/incoming/InComingFloatData.kt
  33. 4 7
      module/call/src/main/java/com/adealink/weparty/call/view/floatview/incoming/InComingFloatView.kt
  34. 1 1
      module/call/src/main/java/com/adealink/weparty/call/view/floatview/incoming/IncomingCallReceiver.kt
  35. 1 2
      module/call/src/main/java/com/adealink/weparty/call/view/floatview/incoming/IncomingNotificationView.kt
  36. 1 1
      module/call/src/main/java/com/adealink/weparty/call/view/floatview/incoming/IncomingView.kt
  37. 2 0
      module/call/src/main/java/com/tencent/qcloud/tuikit/tuicallkit/data/Constants.kt
  38. 47 68
      module/call/src/main/java/com/tencent/qcloud/tuikit/tuicallkit/internal/ServiceInitializer.kt
  39. 20 43
      module/call/src/main/java/com/tencent/qcloud/tuikit/tuicallkit/manager/EngineManager.kt
  40. 1 1
      module/call/src/main/java/com/tencent/qcloud/tuikit/tuicallkit/state/TUICallState.kt
  41. 0 231
      module/call/src/main/java/com/tencent/qcloud/tuikit/tuicallkit/view/component/floatview/FloatWindowService.kt
  42. 0 5
      module/call/src/main/java/com/tencent/qcloud/tuikit/tuicallkit/viewmodel/component/floatview/FloatingWindowViewModel.kt
  43. 6 4
      module/call/src/main/res/values-ar/strings.xml
  44. 6 4
      module/call/src/main/res/values-zh/strings.xml
  45. 2 0
      module/call/src/main/res/values/dimens.xml
  46. 6 4
      module/call/src/main/res/values/strings.xml

+ 1 - 0
app/src/main/java/com/adealink/weparty/commonui/widget/floatview/BaseWindowManager.kt

@@ -15,6 +15,7 @@ abstract class BaseWindowManager {
 
     abstract fun updateViewLayout(view: BaseFloatView, params: WindowManager.LayoutParams)
     abstract fun findFloatViewByType(type: String): BaseFloatView?
+    abstract fun isFloatViewAdded(type: String): Boolean
     abstract fun removeFloatViewByType(type: String, reason: String)
     abstract fun setFloatViewVisibility(type: String, visibility: Int)
 

+ 9 - 0
app/src/main/java/com/adealink/weparty/commonui/widget/floatview/ModeWindowManagerProxy.kt

@@ -65,6 +65,15 @@ class ModeWindowManagerProxy : BaseWindowManager() {
         return null
     }
 
+    override fun isFloatViewAdded(type: String): Boolean {
+        var isViewAdded = false
+        windowManagerMap.values.forEach {
+            val result = it.isFloatViewAdded(type)
+            isViewAdded = isViewAdded or result
+        }
+        return isViewAdded
+    }
+
     override fun removeFloatViewByType(
         type: String, reason: String
     ) {

+ 4 - 0
app/src/main/java/com/adealink/weparty/commonui/widget/floatview/mode/ActivityModeWindowManager.kt

@@ -96,6 +96,10 @@ class ActivityModeWindowManager : BaseWindowManager() {
         return null
     }
 
+    override fun isFloatViewAdded(type: String): Boolean {
+        return findFloatViewByType(type) != null
+    }
+
     override fun removeFloatViewByType(
         type: String, reason: String
     ) {

+ 4 - 0
app/src/main/java/com/adealink/weparty/commonui/widget/floatview/mode/ApplicationModeWindowManager.kt

@@ -187,6 +187,10 @@ class ApplicationModeWindowManager : BaseWindowManager() {
         return null
     }
 
+    override fun isFloatViewAdded(type: String): Boolean {
+        return findFloatViewByType(type) != null
+    }
+
     override fun removeFloatViewByType(
         type: String, reason: String,
     ) {

+ 4 - 0
app/src/main/java/com/adealink/weparty/commonui/widget/floatview/mode/SystemModeWindowManager.kt

@@ -108,6 +108,10 @@ class SystemModeWindowManager : BaseWindowManager() {
         return null
     }
 
+    override fun isFloatViewAdded(type: String): Boolean {
+        return findFloatViewByType(type) != null
+    }
+
     override fun removeFloatViewByType(
         type: String, reason: String
     ) {

+ 4 - 0
app/src/main/java/com/adealink/weparty/commonui/widget/floatview/mode/fix/Android10FixApplicationModeWindowManager.kt

@@ -34,6 +34,10 @@ class Android10FixApplicationModeWindowManager(
         return base.findFloatViewByType(type)
     }
 
+    override fun isFloatViewAdded(type: String): Boolean {
+        return findFloatViewByType(type) != null
+    }
+
     override fun removeFloatViewByType(type: String, reason: String) {
         base.removeFloatViewByType(type, reason)
     }

+ 4 - 2
app/src/main/java/com/adealink/weparty/commonui/widget/floatview/view/BaseDragFloatView.kt

@@ -190,8 +190,10 @@ abstract class BaseDragFloatView(baseFloatData: IBaseFloatData) : BaseFloatView(
             width = getLayoutParamWidth()
             height = getLayoutParamHeight()
             format = PixelFormat.TRANSLUCENT
-            flags =
-                WindowManager.LayoutParams.FLAG_WATCH_OUTSIDE_TOUCH or WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE or WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL
+            flags = (WindowManager.LayoutParams.FLAG_WATCH_OUTSIDE_TOUCH
+                    or WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
+                    or WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL
+                    or WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS)
             gravity = Gravity.START or Gravity.TOP
             val layoutX = getLayoutParamX()
             val layoutY = getLayoutParamY()

+ 8 - 0
app/src/main/java/com/adealink/weparty/module/call/CallModule.kt

@@ -39,6 +39,10 @@ object CallModule : BaseDynamicModule<ICallService>(ICallService::class), ICallS
                 return null
             }
 
+            override fun getCallingFloatView(data: IBaseFloatData): BaseFloatView? {
+                return null
+            }
+
             override fun getCallViewModel(owner: ViewModelStoreOwner): ICallViewModel? {
                 return null
             }
@@ -104,6 +108,10 @@ object CallModule : BaseDynamicModule<ICallService>(ICallService::class), ICallS
         return getService().getIncomingFloatView(data)
     }
 
+    override fun getCallingFloatView(data: IBaseFloatData): BaseFloatView? {
+        return getService().getCallingFloatView(data)
+    }
+
     override fun getCallViewModel(owner: ViewModelStoreOwner): ICallViewModel? {
         return getService().getCallViewModel(owner)
     }

+ 2 - 0
app/src/main/java/com/adealink/weparty/module/call/ICallService.kt

@@ -26,6 +26,8 @@ interface ICallService : IService<ICallService>, IMediaOperatorGet {
 
     fun getIncomingFloatView(data: IBaseFloatData): BaseFloatView?
 
+    fun getCallingFloatView(data: IBaseFloatData): BaseFloatView?
+
     fun getCallViewModel(owner: ViewModelStoreOwner): ICallViewModel?
 
     fun isLogin(): Boolean

+ 2 - 0
app/src/main/java/com/adealink/weparty/widget/floatview/FloatViewFactory.kt

@@ -28,6 +28,7 @@ class FloatViewFactory : IFloatViewFactory {
         const val NEW_MESSAGE = "new_message"
         const val PROFILE_MUSIC= "profile_music"
         const val CALL_1V1_INCOMING = "call_1v1_incoming"
+        const val CALL_1V1_CALLING = "call_1v1_calling"
         const val LEVEL_UPGRADE_HEADLINE = "level_upgrade_headline"
     }
 
@@ -42,6 +43,7 @@ class FloatViewFactory : IFloatViewFactory {
             NEW_MESSAGE -> MessageModule.getNewMessageFloatView(data)
             PROFILE_MUSIC -> ProfileModule.getProfileMusicFloatView(data)
             CALL_1V1_INCOMING -> CallModule.getIncomingFloatView(data)
+            CALL_1V1_CALLING -> CallModule.getCallingFloatView(data)
             LEVEL_UPGRADE_HEADLINE -> LevelModule.getLevelUpgradeHeadlineFloatView(data)
             else -> null
         }

+ 1 - 6
module/call/src/main/AndroidManifest.xml

@@ -59,13 +59,8 @@
             android:enabled="true"
             android:exported="false" />
 
-        <service
-            android:name="com.tencent.qcloud.tuikit.tuicallkit.view.component.floatview.FloatWindowService"
-            android:enabled="true"
-            android:exported="false" />
-
         <receiver
-            android:name=".view.floatview.IncomingCallReceiver"
+            android:name=".view.floatview.incoming.IncomingCallReceiver"
             android:enabled="true"
             android:exported="false">
             <intent-filter>

+ 3 - 17
module/call/src/main/java/com/adealink/weparty/call/CallActivity.kt

@@ -28,7 +28,6 @@ import com.tencent.qcloud.tuikit.tuicallkit.manager.EngineManager
 import com.tencent.qcloud.tuikit.tuicallkit.state.TUICallState
 import com.tencent.qcloud.tuikit.tuicallkit.utils.DeviceUtils
 import com.tencent.qcloud.tuikit.tuicallkit.utils.PermissionRequest
-import com.tencent.qcloud.tuikit.tuicallkit.view.component.floatview.FloatWindowService
 import com.tencent.qcloud.tuikit.tuicallkit.view.component.videolayout.VideoViewFactory
 import com.trtc.tuikit.common.livedata.Observer
 
@@ -51,9 +50,6 @@ class CallActivity : BaseActivity() {
         if (it == TUICallDefine.Status.None) {
             finishActivity()
             VideoViewFactory.instance.clear()
-            if (TUICallDefine.Status.None == TUICallState.instance.selfUser.get().callStatus.get()) {
-                FloatWindowService.stopService()
-            }
         }
     }
 
@@ -109,9 +105,6 @@ class CallActivity : BaseActivity() {
         val notificationManager = getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager?
         notificationManager?.cancelAll()
 
-        if (DeviceUtils.isServiceRunning(application, FloatWindowService::class.java.getName())) {
-            FloatWindowService.stopService()
-        }
         TUICore.notifyEvent(Constants.EVENT_VIEW_STATE_CHANGED, Constants.EVENT_SHOW_FULL_VIEW, HashMap())
         PermissionRequest.requestPermissions(application, TUICallState.instance.mediaType.get(),
             object : PermissionCallback() {
@@ -136,20 +129,13 @@ class CallActivity : BaseActivity() {
         if (intent.action == Constants.ACCEPT_CALL_ACTION) {
             Log.d(TAG_CALL_CHAT, "IncomingView -> startActivityByAction")
             callManager.accept(null, startFullScreenView = false)
-//            EngineManager.instance.accept(null)
-//            if (TUICallState.instance.mediaType.get() == TUICallDefine.MediaType.Video) {
-//                val videoView = VideoViewFactory.instance.createVideoView(
-//                    TUICallState.instance.selfUser.get(), application
-//                )
-//
-//                EngineManager.instance.openCamera(
-//                    TUICallState.instance.isFrontCamera.get(), videoView?.getVideoView(), null
-//                )
-//            }
         }
     }
 
+    @SuppressLint("MissingSuperCall")
     override fun onBackPressed() {
+        //返回按键触发浮窗
+        callManager.showCallingFloatWindow()
     }
 
     override fun onDestroy() {

+ 8 - 2
module/call/src/main/java/com/adealink/weparty/call/CallServiceImpl.kt

@@ -19,8 +19,10 @@ import com.adealink.weparty.call.datasource.local.CallLocalService
 import com.adealink.weparty.call.manager.callLoginManager
 import com.adealink.weparty.call.manager.callManager
 import com.adealink.weparty.call.manager.callPingManager
-import com.adealink.weparty.call.view.floatview.InComingFloatData
-import com.adealink.weparty.call.view.floatview.InComingFloatView
+import com.adealink.weparty.call.view.floatview.calling.CallingFloatData
+import com.adealink.weparty.call.view.floatview.calling.CallingFloatView
+import com.adealink.weparty.call.view.floatview.incoming.InComingFloatData
+import com.adealink.weparty.call.view.floatview.incoming.InComingFloatView
 import com.adealink.weparty.call.viewmodel.CallViewModel
 import com.adealink.weparty.call.viewmodel.CallViewModelFactory
 import com.adealink.weparty.commonui.BaseActivity
@@ -99,6 +101,10 @@ class CallServiceImpl : ICallService {
         return InComingFloatView(data as InComingFloatData)
     }
 
+    override fun getCallingFloatView(data: IBaseFloatData): BaseFloatView {
+        return CallingFloatView(data as CallingFloatData)
+    }
+
     override fun getCallViewModel(owner: ViewModelStoreOwner): ICallViewModel {
         return ViewModelProvider(owner, CallViewModelFactory())[CallViewModel::class.java]
     }

+ 137 - 77
module/call/src/main/java/com/adealink/weparty/call/WenextUICallKitImpl.kt

@@ -10,14 +10,16 @@ import com.adealink.frame.util.AppUtil
 import com.adealink.weparty.call.constant.TAG_CALL_FLOW
 import com.adealink.weparty.call.constant.TAG_CALL_INCOMING_VIEW
 import com.adealink.weparty.call.util.debugToast
-import com.adealink.weparty.call.view.IInComing
-import com.adealink.weparty.call.view.floatview.InComingFloatData
-import com.adealink.weparty.call.view.floatview.InComingFloatView
-import com.adealink.weparty.call.view.floatview.IncomingNotificationView
+import com.adealink.weparty.call.view.floatview.incoming.IInComing
+import com.adealink.weparty.call.view.floatview.incoming.InComingFloatData
+import com.adealink.weparty.call.view.floatview.incoming.InComingFloatView
+import com.adealink.weparty.call.view.floatview.incoming.IncomingNotificationView
+import com.adealink.weparty.commonui.widget.floatview.WindowManagerProxy
 import com.adealink.weparty.commonui.widget.floatview.data.IBaseFloatData
 import com.adealink.weparty.module.call.Call
 import com.adealink.weparty.module.message.Message
 import com.adealink.weparty.module.profile.data.UserInfo
+import com.adealink.weparty.widget.floatview.FloatViewFactory
 import com.tencent.cloud.tuikit.engine.call.TUICallDefine
 import com.tencent.cloud.tuikit.engine.call.TUICallEngine
 import com.tencent.cloud.tuikit.engine.common.TUICommonDefine
@@ -40,6 +42,7 @@ import com.tencent.qcloud.tuikit.tuicallkit.utils.DeviceUtils
 import com.tencent.qcloud.tuikit.tuicallkit.utils.PermissionRequest
 import com.tencent.qcloud.tuikit.tuicallkit.utils.ScreenWakeupHelper
 import com.tencent.qcloud.tuikit.tuicallkit.utils.UserInfoUtils
+import com.tencent.trtc.TRTCCloudDef
 import com.tencent.trtc.TRTCCloudListener
 
 class WenextUICallKitImpl private constructor(context: Context) : TUICallKit(), ITUINotification {
@@ -121,23 +124,23 @@ class WenextUICallKitImpl private constructor(context: Context) : TUICallKit(),
 
     fun queryOfflineCall() {
         Log.d(TAG_CALL_FLOW, "queryOfflineCall start")
-        if (TUICallDefine.Status.Accept != TUICallState.instance.selfUser.get().callStatus.get()) {
-            val role: TUICallDefine.Role = TUICallState.instance.selfUser.get().callRole.get()
-            val mediaType: TUICallDefine.MediaType = TUICallState.instance.mediaType.get()
-            if (TUICallDefine.Role.None == role || TUICallDefine.MediaType.Unknown == mediaType) {
-                return
-            }
+        val selfUser = TUICallState.instance.selfUser.get()
+        if (TUICallDefine.Status.Accept == selfUser.callStatus.get()) {
+            return
+        }
 
-            //The received call has been processed in #onCallReceived
-            if (TUICallDefine.Role.Called == role && PermissionRequester.newInstance(PermissionRequester.BG_START_PERMISSION)
-                    .has()
-            ) {
-                return
-            }
-            Router.build(context, Call.Call.PATH)
-                .setFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
-                .start()
+        val role = selfUser.callRole.get()
+        val mediaType = TUICallState.instance.mediaType.get()
+        if (TUICallDefine.Role.None == role || TUICallDefine.MediaType.Unknown == mediaType) {
+            Log.w(TAG_CALL_FLOW, "queryOfflineCall, current status is Unknown")
+            return
         }
+
+        if (TUICallDefine.Role.Called == role && PermissionRequester.newInstance(PermissionRequester.BG_START_PERMISSION).has()
+        ) {
+            return
+        }
+        handleNewCallWhenAppInForeground()
     }
 
     private fun registerCallingEvent() {
@@ -151,9 +154,12 @@ class WenextUICallKitImpl private constructor(context: Context) : TUICallKit(),
         )
 
         TUICore.registerEvent(Constants.EVENT_TUICALLKIT_CHANGED, Constants.EVENT_START_INCOMING_VIEW, this)
+        TUICore.registerEvent(Constants.EVENT_TUICALLKIT_CHANGED, Constants.EVENT_START_CALLING_VIEW, this)
 
         //注册RTC回调
         TUICallEngine.createInstance(context).trtcCloudInstance.addListener(mTRTCCloudListener)
+        //设置禁用掉重力感应
+        TUICallEngine.createInstance(context).trtcCloudInstance.setGSensorMode(TRTCCloudDef.TRTC_GSENSOR_MODE_DISABLE)
     }
 
     private val mTRTCCloudListener: TRTCCloudListener = object : TRTCCloudListener() {
@@ -186,6 +192,8 @@ class WenextUICallKitImpl private constructor(context: Context) : TUICallKit(),
         if (Constants.EVENT_TUICALLKIT_CHANGED == key) {
             if (Constants.EVENT_START_INCOMING_VIEW == subKey) {
                 handleNewCall()
+            } else if (Constants.EVENT_START_CALLING_VIEW == subKey) {
+                showCallingView()
             }
         }
     }
@@ -200,77 +208,109 @@ class WenextUICallKitImpl private constructor(context: Context) : TUICallKit(),
             callingVibratorFeature = CallingVibratorFeature(context)
             screenWakeupHelper?.releaseLock()
 
-            val hasFloatPermission = PermissionRequester.newInstance(PermissionRequester.FLOAT_PERMISSION).has()
-            val isAppInBackground: Boolean = !DeviceUtils.isAppRunningForeground(context)
-            val hasBgPermission = PermissionRequester.newInstance(PermissionRequester.BG_START_PERMISSION).has()
-            val hasNotificationPermission = PermissionRequest.isNotificationEnabled()
-            val isIMPage = isIMActivity()
-            val isFCMData = isFCMDataNotification()
-            val isScreenLocked = DeviceUtils.isScreenLocked(context)
-
-            Log.d(
-                TAG_CALL_INCOMING_VIEW, "handleNewCall, isScreenLocked: $isScreenLocked, " +
-                        "isAppInBackground: $isAppInBackground, " +
-                        "floatPermission: $hasFloatPermission, " +
-                        "backgroundStartPermission: $hasBgPermission, " +
-                        "notificationPermission: $hasNotificationPermission , " +
-                        "isFCMDataNotification: $isFCMData, " +
-                        "enableIncomingBanner:${TUICallState.instance.enableIncomingBanner}"
-            )
+            if (BuildConfig.DEBUG) {
+                //val hasFloatPermission = PermissionRequester.newInstance(PermissionRequester.FLOAT_PERMISSION).has()
+                val isAppInBackground: Boolean = !DeviceUtils.isAppRunningForeground(context)
+                val hasBgPermission = PermissionRequester.newInstance(PermissionRequester.BG_START_PERMISSION).has()
+                val hasNotificationPermission = PermissionRequest.isNotificationEnabled()
+                val isIMPage = isIMActivity()
+                val isFCMData = isFCMDataNotification()
+                val isScreenLocked = DeviceUtils.isScreenLocked(context)
+
+                Log.d(
+                    TAG_CALL_INCOMING_VIEW, "handleNewCall, isScreenLocked: $isScreenLocked, " +
+                            "isAppInBackground: $isAppInBackground, " +
+                            "isIMPage: $isIMPage, " +
+                            //"floatPermission: $hasFloatPermission, " +
+                            "backgroundStartPermission: $hasBgPermission, " +
+                            "notificationPermission: $hasNotificationPermission , " +
+                            "isFCMDataNotification: $isFCMData, " +
+                            "enableIncomingBanner:${TUICallState.instance.enableIncomingBanner}"
+                )
+            }
 
+            val isScreenLocked = DeviceUtils.isScreenLocked(context)
             //锁屏
             if (isScreenLocked) {
-                if (hasNotificationPermission) {
-                    Log.d(TAG_CALL_INCOMING_VIEW, "handleNewCall, screen is locked, show incoming notification")
-                    startSmallIncomingView(IncomingNotificationView(context))
-                } else {
-                    Log.d(TAG_CALL_INCOMING_VIEW, "handleNewCall, screen is locked, show fullScreen")
-                    startFullScreenView()
-                }
+                handleNewCallWhenScreenLocked()
                 return@post
             }
 
+            val isAppInBackground: Boolean = !DeviceUtils.isAppRunningForeground(context)
             if (isAppInBackground) {
                 //应用后台, 启动顺序, 悬浮窗 > 通知 > 后台弹出界面
-                when {
-                    hasFloatPermission -> {
-                        startSmallIncomingView(
-                            InComingFloatView(InComingFloatData(IBaseFloatData.MODE_SYSTEM))
-                        )
-                    }
+                handleNewCallWhenAppInBackground()
+                return@post
+            }
 
-                    isFCMData && hasNotificationPermission -> {
-                        startSmallIncomingView(IncomingNotificationView(context))
-                    }
+            handleNewCallWhenAppInForeground()
+        }
+    }
 
-                    hasBgPermission -> {
-                        startSmallIncomingView(IncomingNotificationView(context)) //startFullScreenView()
-                    }
+    /**
+     * 锁屏
+     */
+    private fun handleNewCallWhenScreenLocked() {
+        val hasNotificationPermission = PermissionRequest.isNotificationEnabled()
+        if (hasNotificationPermission) {
+            Log.d(TAG_CALL_INCOMING_VIEW, "handleNewCall, screen is locked, show incoming notification")
+            startSmallIncomingView(IncomingNotificationView(context))
+        } else {
+            Log.d(TAG_CALL_INCOMING_VIEW, "handleNewCall, screen is locked, show fullScreen")
+            startFullScreenView()
+        }
+    }
 
-                    else -> {
-                        Log.w(TAG_CALL_INCOMING_VIEW, "App is in background with no permission")
-                    }
-                }
-                return@post
-            } else {
-                //应用前台, 启动顺序, IM页面
-                when {
-                    isIMPage -> {
-                        startFullScreenView()
-                    }
+    /**
+     * 应用后台
+     */
+    private fun handleNewCallWhenAppInBackground() {
+//        val hasFloatPermission = PermissionRequester.newInstance(PermissionRequester.FLOAT_PERMISSION).has()
+//        val hasBgPermission = PermissionRequester.newInstance(PermissionRequester.BG_START_PERMISSION).has()
+        val hasNotificationPermission = PermissionRequest.isNotificationEnabled()
+        val isFCMData = isFCMDataNotification()
+        when {
+//            hasFloatPermission -> {
+//                startSmallIncomingView(
+//                    InComingFloatView(InComingFloatData(IBaseFloatData.MODE_SYSTEM))
+//                )
+//            }
+
+            isFCMData && hasNotificationPermission -> {
+                startSmallIncomingView(IncomingNotificationView(context))
+            }
 
-                    hasFloatPermission -> {
-                        startSmallIncomingView(
-                            InComingFloatView(InComingFloatData(IBaseFloatData.MODE_SYSTEM))
-                        )
-                    }
+//            hasBgPermission -> {
+//                startSmallIncomingView(IncomingNotificationView(context)) //startFullScreenView()
+//            }
 
-                    else -> {
-                        startSmallIncomingView(
-                            InComingFloatView(InComingFloatData(IBaseFloatData.MODE_APPLICATION))
-                        )
-                    }
-                }
+            else -> {
+                Log.w(TAG_CALL_INCOMING_VIEW, "App is in background with no permission")
+            }
+        }
+    }
+
+    /**
+     * 应用前台
+     */
+    private fun handleNewCallWhenAppInForeground() {
+        //val hasFloatPermission = PermissionRequester.newInstance(PermissionRequester.FLOAT_PERMISSION).has()
+        val isIMPage = isIMActivity()
+        when {
+            isIMPage -> {
+                startFullScreenView()
+            }
+
+//            hasFloatPermission -> {
+//                startSmallIncomingView(
+//                    InComingFloatView(InComingFloatData(IBaseFloatData.MODE_SYSTEM))
+//                )
+//            }
+
+            else -> {
+                startSmallIncomingView(
+                    InComingFloatView(InComingFloatData(IBaseFloatData.MODE_APPLICATION))
+                )
             }
         }
     }
@@ -325,6 +365,26 @@ class WenextUICallKitImpl private constructor(context: Context) : TUICallKit(),
         })
     }
 
+    fun showCallingView() {
+        val selfCallStatus = TUICallState.instance.selfUser.get().callStatus.get()
+        if (TUICallDefine.Status.None == selfCallStatus) {
+            Log.d(TAG_CALL_FLOW, "startCallingView return, for selfUser.callStatus(${selfCallStatus}) == None")
+            return
+        }
+
+        val floatViewAdded = WindowManagerProxy.getWindowManager().isFloatViewAdded(FloatViewFactory.CALL_1V1_CALLING)
+        if (floatViewAdded) {
+            Log.d(TAG_CALL_FLOW, "startCallingView return, for callingFloatView is show")
+            return
+        }
+
+        if (TUICallState.instance.scene.get() == TUICallDefine.Scene.GROUP_CALL) {
+            Log.d(TAG_CALL_FLOW, "startCallingView return, for unsupported GROUP_CALL scene")
+            return
+        }
+        EngineManager.instance.showCallingFloatWindow()
+    }
+
     private fun initCallEngine() {
         TUICallEngine.createInstance(context).init(
             TUILogin.getSdkAppId(), TUILogin.getLoginUser(), TUILogin.getUserSig(), object : TUICommonDefine.Callback {

+ 2 - 2
module/call/src/main/java/com/adealink/weparty/call/chat/comp/ChatRoomTopComp.kt

@@ -7,6 +7,7 @@ import com.adealink.frame.base.fastLazy
 import com.adealink.frame.mvvm.view.ViewComponent
 import com.adealink.frame.router.Router
 import com.adealink.weparty.call.databinding.LayoutCallChatRoomTopBarBinding
+import com.adealink.weparty.call.manager.callManager
 import com.adealink.weparty.call.util.playDiamondAddAnim
 import com.adealink.weparty.commonui.dialogfragment.BaseDialogFragment
 import com.adealink.weparty.commonui.ext.gone
@@ -16,7 +17,6 @@ import com.adealink.weparty.module.userprotect.data.ReportFrom
 import com.adealink.weparty.module.userprotect.data.ReportType
 import com.adealink.weparty.module.wallet.WalletModule
 import com.adealink.weparty.module.wallet.data.Currency
-import com.tencent.qcloud.tuikit.tuicallkit.manager.EngineManager
 import com.tencent.qcloud.tuikit.tuicallkit.state.TUICallState
 import com.trtc.tuikit.common.livedata.Observer
 
@@ -49,7 +49,7 @@ class ChatRoomTopComp(
             doReport()
         }
         binding.ivMini.setOnClickListener {
-            EngineManager.instance.showFloatWindow()
+            callManager.showCallingFloatWindow()
         }
         binding.clCoins.setOnClickListener {
             goRecharge()

+ 4 - 12
module/call/src/main/java/com/adealink/weparty/call/chat/fragment/ChatWaitingFragment.kt

@@ -1,29 +1,21 @@
 package com.adealink.weparty.call.chat.fragment
 
-import android.text.SpannableStringBuilder
-import android.text.Spanned
 import android.widget.FrameLayout
 import androidx.constraintlayout.widget.ConstraintLayout
 import androidx.core.view.updateLayoutParams
-import com.adealink.frame.aab.util.getCompatDrawable
 import com.adealink.frame.aab.util.getCompatString
-import com.adealink.frame.ext.safeSetSpan
 import com.adealink.frame.mvvm.view.viewBinding
 import com.adealink.weparty.call.R
-import com.adealink.weparty.call.comp.BgComp
-import com.adealink.weparty.call.comp.UserInfoComp
 import com.adealink.weparty.call.chat.widget.CalledWaitingFunctionView
 import com.adealink.weparty.call.chat.widget.CallerWaitingFunctionView
+import com.adealink.weparty.call.comp.BgComp
+import com.adealink.weparty.call.comp.UserInfoComp
 import com.adealink.weparty.call.databinding.FragmentCallChatWaitingBinding
-import com.adealink.weparty.call.datasource.local.CallLocalService
+import com.adealink.weparty.call.manager.callManager
 import com.adealink.weparty.call.util.getCallWaitingTips
 import com.adealink.weparty.call.widget.BaseCallFragment
-import com.adealink.weparty.commonui.ext.dp
-import com.adealink.weparty.commonui.widget.CenterImageSpan
 import com.qmuiteam.qmui.widget.util.QMUIStatusBarHelper
-import com.tencent.qcloud.tuikit.tuicallkit.manager.EngineManager
 import com.tencent.qcloud.tuikit.tuicallkit.state.TUICallState
-import com.adealink.weparty.R as APP_R
 
 /**
  * TUICallDefine.Status.Waiting
@@ -38,7 +30,7 @@ class ChatWaitingFragment : BaseCallFragment(R.layout.fragment_call_chat_waiting
             topMargin = QMUIStatusBarHelper.getStatusbarHeight(context)
         }
         binding.ivMini.setOnClickListener {
-            EngineManager.instance.showFloatWindow()
+            callManager.showCallingFloatWindow()
         }
         inflateFunctionView()
         if (TUICallState.instance.selfUser.get().isCaller()) {

+ 0 - 11
module/call/src/main/java/com/adealink/weparty/call/comp/CallGiftComp.kt

@@ -185,17 +185,6 @@ class CallGiftComp(
                     if (toUid == null || toUid == 0L) {
                         return
                     }
-//                    runOnUiThread(
-//                        {
-//                            val act = activity ?: return@runOnUiThread
-//                            showDialogFragment<SendFreeGiftFeedbackDialog>(
-//                                act.supportFragmentManager,
-//                                Bundle().apply {
-//                                    putLong(Room.FreeGiftFeedbackDialog.EXTRA_GIFT_ID, returnGiftId)
-//                                    putLong(Room.FreeGiftFeedbackDialog.EXTRA_TO_UID, toUid)
-//                                })
-//                        }, 3_000L
-//                    ) //3秒是普通动画播放的时间
                 }
             })
             luckyGiftRewardNotifyLD.observeWithoutCache(viewLifecycleOwner) { luckyGiftRewardNotify ->

+ 1 - 0
module/call/src/main/java/com/adealink/weparty/call/constant/Tags.kt

@@ -11,6 +11,7 @@ const val TAG_CALL_ENGINE = "${TAG_CALL}_engine"
 const val TAG_CALL_FLOAT_WINDOW = "${TAG_CALL}_float_window"
 const val TAG_CALL_INCOMING_NOTIFICATION = "${TAG_CALL}_incoming_notification"
 const val TAG_CALL_INCOMING_VIEW = "${TAG_CALL}_incoming_view"
+const val TAG_CALL_FLOAT_VIEW = "${TAG_CALL}_float_view"
 
 const val TAG_CALL_CHAT = "${TAG_CALL}_chat"
 

+ 0 - 5
module/call/src/main/java/com/adealink/weparty/call/interceptor/EnterCallUriInterceptor.kt

@@ -28,11 +28,6 @@ class EnterCallUriInterceptor : UriInterceptor {
     override fun intercept(chain: UriInterceptor.Chain) {
         val request = chain.request()
         val context = request.ctx ?: return
-//        if (activity == null) {
-//            Log.e(TAG_CALL_ENTER, "EnterCallUriInterceptor, activity is null")
-//            chain.abort()
-//            return
-//        }
 
         CoroutineScope(Dispatcher.UI).launch {
             enterCall(context, object : UriInterceptor.Chain {

+ 7 - 1
module/call/src/main/java/com/adealink/weparty/call/manager/CallManager.kt

@@ -47,7 +47,9 @@ import com.adealink.weparty.room.data.SocketLevelRoomReq
 import com.tencent.cloud.tuikit.engine.call.TUICallDefine
 import com.tencent.cloud.tuikit.engine.call.TUICallDefine.CallParams
 import com.tencent.cloud.tuikit.engine.common.TUICommonDefine
+import com.tencent.qcloud.tuicore.TUICore
 import com.tencent.qcloud.tuicore.permission.PermissionCallback
+import com.tencent.qcloud.tuikit.tuicallkit.data.Constants
 import com.tencent.qcloud.tuikit.tuicallkit.data.OfflinePushInfoConfig
 import com.tencent.qcloud.tuikit.tuicallkit.data.SettingsConfig
 import com.tencent.qcloud.tuikit.tuicallkit.manager.EngineManager
@@ -116,7 +118,7 @@ class CallManager : BaseFrame<ICallListener>(), ICallManager {
     }
 
     override fun init() {
-        //TUICore.registerEvent(Constants.EVENT_TUICALLKIT_CHANGED, Constants.EVENT_START_INCOMING_VIEW, this)
+
     }
 
     override fun onCallBegin() {
@@ -131,6 +133,10 @@ class CallManager : BaseFrame<ICallListener>(), ICallManager {
         leaveRoom(joinedRoomId)
     }
 
+    override fun showCallingFloatWindow() {
+        TUICore.notifyEvent(Constants.EVENT_TUICALLKIT_CHANGED, Constants.EVENT_START_CALLING_VIEW, HashMap())
+    }
+
     override fun getRoomId(): Long? {
         return joinedRoomId
     }

+ 5 - 0
module/call/src/main/java/com/adealink/weparty/call/manager/ICallManager.kt

@@ -60,6 +60,11 @@ interface ICallManager : IBaseFrame<ICallListener> {
      */
     fun onCallEnd()
 
+    /**
+     * 显示悬浮窗
+     */
+    fun showCallingFloatWindow()
+
     fun getRoomId(): Long?
 
     fun isRoomJoiningOrJoined(): Boolean

+ 0 - 3
module/call/src/main/java/com/adealink/weparty/call/video/comp/VideoCallerComp.kt

@@ -33,9 +33,6 @@ class VideoCallerComp(
     }
 
     override fun removeObserver() {
-//        if (TUICallState.instance.getCallerUser()?.callStatus?.get() != TUICallDefine.Status.Accept) {
-//            videoViewBig?.removeObserver()
-//        }
     }
 
     private fun initView() {

+ 0 - 2
module/call/src/main/java/com/adealink/weparty/call/video/comp/VideoRoomComp.kt

@@ -145,13 +145,11 @@ class VideoRoomComp(
             setSmallRenderViewOrientation()
 
             if (TUICallState.instance.showLargeViewUserId.get() == bigVideoUser?.id) {
-                //viewModel.reverseRenderLayout(false)
                 TUICallState.instance.showLargeViewUserId.set(smallVideoUser?.id)
 
                 smallVideoContainer?.addView(bigVideoView)
                 bigVideoContainer?.addView(smallVideoView)
             } else {
-                //viewModel.reverseRenderLayout(true)
                 TUICallState.instance.showLargeViewUserId.set(bigVideoUser?.id)
 
                 smallVideoContainer?.addView(smallVideoView)

+ 2 - 2
module/call/src/main/java/com/adealink/weparty/call/video/comp/VideoRoomTopComp.kt

@@ -7,6 +7,7 @@ import com.adealink.frame.base.fastLazy
 import com.adealink.frame.mvvm.view.ViewComponent
 import com.adealink.frame.router.Router
 import com.adealink.weparty.call.databinding.LayoutCallVideoRoomTopBarBinding
+import com.adealink.weparty.call.manager.callManager
 import com.adealink.weparty.call.util.playDiamondAddAnim
 import com.adealink.weparty.commonui.dialogfragment.BaseDialogFragment
 import com.adealink.weparty.commonui.ext.gone
@@ -16,7 +17,6 @@ import com.adealink.weparty.module.userprotect.data.ReportFrom
 import com.adealink.weparty.module.userprotect.data.ReportType
 import com.adealink.weparty.module.wallet.WalletModule
 import com.adealink.weparty.module.wallet.data.Currency
-import com.tencent.qcloud.tuikit.tuicallkit.manager.EngineManager
 import com.tencent.qcloud.tuikit.tuicallkit.state.TUICallState
 import com.trtc.tuikit.common.livedata.Observer
 
@@ -49,7 +49,7 @@ class VideoRoomTopComp(
             doReport()
         }
         binding.ivMini.setOnClickListener {
-            EngineManager.instance.showFloatWindow()
+            callManager.showCallingFloatWindow()
         }
         binding.clCoins.setOnClickListener {
             goRecharge()

+ 2 - 2
module/call/src/main/java/com/adealink/weparty/call/video/fragment/VideoCalledFragment.kt

@@ -8,12 +8,12 @@ import com.adealink.weparty.call.R
 import com.adealink.weparty.call.comp.BgComp
 import com.adealink.weparty.call.comp.UserInfoComp
 import com.adealink.weparty.call.databinding.FragmentCallVideoCalledWaitingBinding
+import com.adealink.weparty.call.manager.callManager
 import com.adealink.weparty.call.util.getCallWaitingTips
 import com.adealink.weparty.call.video.widget.CalledWaitingFunctionView
 import com.adealink.weparty.call.widget.BaseCallFragment
 import com.adealink.weparty.call.widget.ICallView
 import com.qmuiteam.qmui.widget.util.QMUIStatusBarHelper
-import com.tencent.qcloud.tuikit.tuicallkit.manager.EngineManager
 import com.tencent.qcloud.tuikit.tuicallkit.state.TUICallState
 
 class VideoCalledFragment : BaseCallFragment(R.layout.fragment_call_video_called_waiting) {
@@ -27,7 +27,7 @@ class VideoCalledFragment : BaseCallFragment(R.layout.fragment_call_video_called
             topMargin = QMUIStatusBarHelper.getStatusbarHeight(context)
         }
         binding.ivMini.setOnClickListener {
-            EngineManager.instance.showFloatWindow()
+            callManager.showCallingFloatWindow()
         }
         inflateFunctionView()
         binding.tvCallDetail.text = getCallWaitingTips()

+ 2 - 2
module/call/src/main/java/com/adealink/weparty/call/video/fragment/VideoCallerFragment.kt

@@ -7,6 +7,7 @@ import com.adealink.frame.mvvm.view.viewBinding
 import com.adealink.weparty.call.R
 import com.adealink.weparty.call.comp.BgComp
 import com.adealink.weparty.call.databinding.FragmentCallVideoCallerWaitingBinding
+import com.adealink.weparty.call.manager.callManager
 import com.adealink.weparty.call.util.getCallWaitingTips
 import com.adealink.weparty.call.video.comp.UserInfoComp
 import com.adealink.weparty.call.video.comp.VideoCallerComp
@@ -16,7 +17,6 @@ import com.adealink.weparty.call.widget.ICallView
 import com.adealink.weparty.commonui.ext.gone
 import com.adealink.weparty.commonui.ext.show
 import com.qmuiteam.qmui.widget.util.QMUIStatusBarHelper
-import com.tencent.qcloud.tuikit.tuicallkit.manager.EngineManager
 import com.tencent.qcloud.tuikit.tuicallkit.state.TUICallState
 import com.trtc.tuikit.common.livedata.Observer
 
@@ -39,7 +39,7 @@ class VideoCallerFragment : BaseCallFragment(R.layout.fragment_call_video_caller
             topMargin = QMUIStatusBarHelper.getStatusbarHeight(context)
         }
         binding.ivMini.setOnClickListener {
-            EngineManager.instance.showFloatWindow()
+            callManager.showCallingFloatWindow()
         }
         inflateFunctionView()
         binding.tvCallDetail.text = getCallWaitingTips()

+ 10 - 0
module/call/src/main/java/com/adealink/weparty/call/view/floatview/calling/CallingFloatData.kt

@@ -0,0 +1,10 @@
+package com.adealink.weparty.call.view.floatview.calling
+
+import com.adealink.weparty.commonui.widget.floatview.data.IBaseFloatData
+import com.adealink.weparty.widget.floatview.FloatViewFactory
+
+class CallingFloatData(private val windowMode: Int) :
+    IBaseFloatData {
+    override fun getType(): String = FloatViewFactory.CALL_1V1_CALLING
+    override fun getWindowMode(): Int = windowMode
+}

+ 132 - 0
module/call/src/main/java/com/adealink/weparty/call/view/floatview/calling/CallingFloatView.kt

@@ -0,0 +1,132 @@
+package com.adealink.weparty.call.view.floatview.calling
+
+import android.content.Intent
+import android.view.View
+import android.view.WindowManager
+import com.adealink.frame.aab.util.getCompatDimensionPixelSize
+import com.adealink.frame.log.Log
+import com.adealink.frame.router.Router
+import com.adealink.frame.util.DisplayUtil
+import com.adealink.weparty.call.R
+import com.adealink.weparty.call.constant.TAG_CALL_FLOAT_VIEW
+import com.adealink.weparty.commonui.ext.dp
+import com.adealink.weparty.commonui.widget.floatview.WindowManagerProxy
+import com.adealink.weparty.commonui.widget.floatview.view.BaseDragFloatView
+import com.adealink.weparty.module.call.Call
+import com.tencent.cloud.tuikit.engine.call.TUICallDefine
+import com.tencent.qcloud.tuicore.ServiceInitializer
+import com.tencent.qcloud.tuicore.TUICore
+import com.tencent.qcloud.tuikit.tuicallkit.data.Constants
+import com.tencent.qcloud.tuikit.tuicallkit.state.TUICallState
+import com.trtc.tuikit.common.livedata.Observer
+
+class CallingFloatView(floatData: CallingFloatData) :
+    BaseDragFloatView(floatData),
+    ICalling {
+
+    private var callStatusObserver = Observer<TUICallDefine.Status> {
+        if (it == TUICallDefine.Status.None) {
+            if (TUICallDefine.Status.None == TUICallState.instance.selfUser.get().callStatus.get()) {
+                cancelCallingView()
+            }
+        }
+    }
+
+    private var callingView: CallingView = CallingView(context)
+
+    init {
+        setContentView(callingView)
+        callingView.setOnCancelCallback(object : CallingView.ICancelViewCallback {
+            override fun onCancel() {
+                cancelCallingView()
+            }
+        })
+        callingView.setOnClickListener {
+            cancelCallingView()
+            if (TUICallState.instance.selfUser.get().callStatus.get() != TUICallDefine.Status.None) {
+                val context = ServiceInitializer.getAppContext()
+                Router.build(context, Call.Call.PATH)
+                    .setFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
+                    .start()
+            }
+        }
+    }
+
+    override fun showCallingView() {
+        Log.d(TAG_CALL_FLOAT_VIEW, "CallingFloatView.showCallingView")
+        TUICallState.instance.isShowFloatView.set(true)
+        addObserver()
+        WindowManagerProxy.getWindowManager().addView(this)
+        TUICore.notifyEvent(Constants.EVENT_VIEW_STATE_CHANGED, Constants.EVENT_SHOW_FLOAT_VIEW, HashMap())
+    }
+
+    private fun addObserver() {
+        TUICallState.instance.selfUser.get().callStatus.observe(callStatusObserver)
+    }
+
+    private fun removeObserver() {
+        TUICallState.instance.selfUser.get().callStatus.removeObserver(callStatusObserver)
+    }
+
+    override fun onCreate() {
+        super.onCreate()
+//        visibility = if (show) View.VISIBLE else View.GONE
+//        animate().translationY(0f).setDuration(300).withEndAction {
+//            animate().setDuration(3000).withEndAction {
+//                animate().translationY(-transY).setDuration(300).withEndAction {
+//                    removeSelf("")
+//                }.start()
+//            }.start()
+//        }.start()
+    }
+
+//    override fun getWindowLayoutParams(): WindowManager.LayoutParams {
+//        return WindowManager.LayoutParams().apply {
+//            width = DisplayUtil.getScreenWidth() - 24.dp()
+//            height = WindowManager.LayoutParams.WRAP_CONTENT
+//            format = PixelFormat.TRANSLUCENT
+//            flags = (WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL
+//                    or WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
+//                    or WindowManager.LayoutParams.FLAG_WATCH_OUTSIDE_TOUCH
+//                    or WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS)
+//            gravity = Gravity.START or Gravity.TOP
+//            x = 12.dp()
+//            y = 0
+//        }
+//    }
+
+    override fun getLayoutParamWidth(): Int {
+        return getCompatDimensionPixelSize(R.dimen.call_calling_float_view_width)
+    }
+
+    override fun getLayoutParamHeight(): Int {
+        return WindowManager.LayoutParams.WRAP_CONTENT
+    }
+
+    override fun getClickableViews(): List<View> {
+        return listOf(callingView)
+    }
+
+    override fun getLayoutParamX(): Int {
+        return DisplayUtil.getScreenWidth() - getLayoutParamWidth() - 20.dp()
+    }
+
+    override fun getLayoutParamY(): Int {
+        return 100.dp()
+    }
+
+    override fun allowFixLocation(): Boolean {
+        return false
+    }
+
+    override fun cancelCallingView() {
+        Log.d(TAG_CALL_FLOAT_VIEW, "CallingFloatView.cancelCallingView")
+        TUICallState.instance.isShowFloatView.set(false)
+        callingView.cancelIncomingView()
+        if (isAttachedToWindow) {
+            WindowManagerProxy.getWindowManager().removeView(this)
+        }
+        removeObserver()
+    }
+
+}

+ 47 - 23
module/call/src/main/java/com/tencent/qcloud/tuikit/tuicallkit/view/component/floatview/FloatingWindowView.kt → module/call/src/main/java/com/adealink/weparty/call/view/floatview/calling/CallingView.kt

@@ -1,4 +1,4 @@
-package com.tencent.qcloud.tuikit.tuicallkit.view.component.floatview
+package com.adealink.weparty.call.view.floatview.calling
 
 import android.content.Context
 import android.content.res.Configuration
@@ -10,12 +10,12 @@ import androidx.appcompat.widget.AppCompatImageView
 import androidx.appcompat.widget.AppCompatTextView
 import androidx.constraintlayout.widget.ConstraintLayout
 import androidx.core.view.updateLayoutParams
+import com.adealink.frame.aab.util.getCompatDimensionPixelSize
 import com.adealink.frame.aab.util.getCompatString
 import com.adealink.frame.image.view.NetworkImageView
 import com.adealink.frame.util.DisplayUtil
 import com.adealink.weparty.call.R
 import com.adealink.weparty.call.util.playDiamondAddAnim
-import com.adealink.weparty.commonui.ext.dp
 import com.adealink.weparty.commonui.ext.dpf
 import com.adealink.weparty.commonui.ext.gone
 import com.adealink.weparty.commonui.ext.show
@@ -35,12 +35,7 @@ import com.adealink.weparty.R as APP_R
 /**
  * 通话浮动视图
  */
-class FloatingWindowView(context: Context) : BaseCallView(context) {
-    companion object {
-        val VIDEO_WIDTH_VERTICAL: Int = 90.dp()
-        val VIDEO_WIDTH_HORIZONTAL: Int = 120.dp()
-    }
-
+class CallingView(context: Context) : BaseCallView(context) {
     private var waitingContainer: View? = null
     private var waitingBgView: NetworkImageView? = null
     private var waitingAvatarView: AvatarView? = null
@@ -64,6 +59,8 @@ class FloatingWindowView(context: Context) : BaseCallView(context) {
 
     private var viewModel: FloatingWindowViewModel = FloatingWindowViewModel()
 
+    private var onCancelCallback: ICancelViewCallback? = null
+
     private val mediaType: MediaType?
         get() = viewModel.mediaType?.get()
 
@@ -104,6 +101,10 @@ class FloatingWindowView(context: Context) : BaseCallView(context) {
         addObserver()
     }
 
+    fun setOnCancelCallback(callback: ICancelViewCallback?) {
+        this.onCancelCallback = callback
+    }
+
     override fun clear() {
         super.clear()
         earnDiamond = 0
@@ -180,25 +181,36 @@ class FloatingWindowView(context: Context) : BaseCallView(context) {
     private fun updateVideoLp(isPortrait: Boolean?) {
         isPortrait ?: return
         val videoView = layoutVideoView ?: return
-        if (isPortrait) {
-            val ratio = DisplayUtil.getScreenWidth() * 1f / DisplayUtil.getScreenHeight()
-            videoView.updateLayoutParams<ConstraintLayout.LayoutParams> {
-                width = VIDEO_WIDTH_VERTICAL
-                height = (VIDEO_WIDTH_VERTICAL / ratio).toInt()
-            }
-        } else {
-            val ratio = DisplayUtil.getScreenWidth() * 1f / DisplayUtil.getScreenHeight()
-            videoView.updateLayoutParams<ConstraintLayout.LayoutParams> {
-                width = VIDEO_WIDTH_HORIZONTAL
-                height = (VIDEO_WIDTH_VERTICAL / ratio).toInt()
-            }
+        val viewWidth = getCompatDimensionPixelSize(R.dimen.call_calling_float_view_width)
+        val ratio = DisplayUtil.getScreenWidth() * 1f / DisplayUtil.getScreenHeight()
+        videoView.updateLayoutParams<ConstraintLayout.LayoutParams> {
+            width = viewWidth
+            height = (viewWidth / ratio).toInt()
         }
+//        if (isPortrait) {
+//            val ratio = DisplayUtil.getScreenWidth() * 1f / DisplayUtil.getScreenHeight()
+//            videoView.updateLayoutParams<ConstraintLayout.LayoutParams> {
+//                width = VIDEO_WIDTH_VERTICAL
+//                height = (VIDEO_WIDTH_VERTICAL / ratio).toInt()
+//            }
+//        } else {
+//            val ratio = DisplayUtil.getScreenWidth() * 1f / DisplayUtil.getScreenHeight()
+//            videoView.updateLayoutParams<ConstraintLayout.LayoutParams> {
+//                width = VIDEO_WIDTH_HORIZONTAL
+//                height = (VIDEO_WIDTH_VERTICAL / ratio).toInt()
+//            }
+//        }
+    }
+
+    fun cancelIncomingView() {
+        VideoViewFactory.instance.clear()
+        clear()
     }
 
     private fun reset() {
         VideoViewFactory.instance.clear()
         clear()
-        viewModel.stopFloatService()
+        onCancelCallback?.onCancel()
     }
 
     private fun updateView(mediaType: MediaType) {
@@ -237,7 +249,11 @@ class FloatingWindowView(context: Context) : BaseCallView(context) {
                 when (callStatus) {
                     TUICallDefine.Status.Waiting -> {
                         waitingContainer?.show()
-                        waitingTextView?.text = getCompatString(R.string.call_wait_response)
+                        waitingTextView?.text = if (TUICallState.instance.selfUser.get().isCaller()) {
+                            getCompatString(R.string.call_caller_wait)
+                        } else {
+                            getCompatString(R.string.call_called_wait)
+                        }
                         chatContainer?.gone()
                     }
 
@@ -257,7 +273,11 @@ class FloatingWindowView(context: Context) : BaseCallView(context) {
                 when (callStatus) {
                     TUICallDefine.Status.Waiting -> {
                         waitingContainer?.show()
-                        waitingTextView?.text = getCompatString(R.string.call_wait_response)
+                        waitingTextView?.text = if (TUICallState.instance.selfUser.get().isCaller()) {
+                            getCompatString(R.string.call_caller_wait)
+                        } else {
+                            getCompatString(R.string.call_called_wait)
+                        }
                         videoContainer?.gone()
                         updateWhenVideoAvailable()
                     }
@@ -373,4 +393,8 @@ class FloatingWindowView(context: Context) : BaseCallView(context) {
         }
     }
 
+    interface ICancelViewCallback {
+        fun onCancel()
+    }
+
 }

+ 7 - 0
module/call/src/main/java/com/adealink/weparty/call/view/floatview/calling/ICalling.kt

@@ -0,0 +1,7 @@
+package com.adealink.weparty.call.view.floatview.calling
+
+interface ICalling {
+    fun showCallingView()
+
+    fun cancelCallingView()
+}

+ 1 - 1
module/call/src/main/java/com/adealink/weparty/call/view/IInComing.kt → module/call/src/main/java/com/adealink/weparty/call/view/floatview/incoming/IInComing.kt

@@ -1,4 +1,4 @@
-package com.adealink.weparty.call.view
+package com.adealink.weparty.call.view.floatview.incoming
 
 import com.tencent.qcloud.tuikit.tuicallkit.data.User
 

+ 1 - 1
module/call/src/main/java/com/adealink/weparty/call/view/floatview/InComingFloatData.kt → module/call/src/main/java/com/adealink/weparty/call/view/floatview/incoming/InComingFloatData.kt

@@ -1,4 +1,4 @@
-package com.adealink.weparty.call.view.floatview
+package com.adealink.weparty.call.view.floatview.incoming
 
 import com.adealink.weparty.commonui.widget.floatview.data.IBaseFloatData
 import com.adealink.weparty.widget.floatview.FloatViewFactory

+ 4 - 7
module/call/src/main/java/com/adealink/weparty/call/view/floatview/InComingFloatView.kt → module/call/src/main/java/com/adealink/weparty/call/view/floatview/incoming/InComingFloatView.kt

@@ -1,4 +1,4 @@
-package com.adealink.weparty.call.view.floatview
+package com.adealink.weparty.call.view.floatview.incoming
 
 import android.app.Activity
 import android.graphics.PixelFormat
@@ -7,7 +7,6 @@ import android.view.WindowManager
 import com.adealink.frame.log.Log
 import com.adealink.frame.util.DisplayUtil
 import com.adealink.weparty.call.constant.TAG_CALL_INCOMING_VIEW
-import com.adealink.weparty.call.view.IInComing
 import com.adealink.weparty.commonui.ext.dp
 import com.adealink.weparty.commonui.widget.floatview.WindowManagerProxy
 import com.adealink.weparty.commonui.widget.floatview.view.BaseFloatView
@@ -17,7 +16,7 @@ import com.tencent.qcloud.tuicore.interfaces.ITUINotification
 import com.tencent.qcloud.tuikit.tuicallkit.data.Constants
 import com.tencent.qcloud.tuikit.tuicallkit.data.User
 import com.tencent.qcloud.tuikit.tuicallkit.state.TUICallState
-import com.adealink.weparty.call.view.floatview.IncomingView.ICancelViewCallback
+import com.adealink.weparty.call.view.floatview.incoming.IncomingView.ICancelViewCallback
 import com.trtc.tuikit.common.livedata.Observer
 
 class InComingFloatView(floatData: InComingFloatData) :
@@ -26,8 +25,6 @@ class InComingFloatView(floatData: InComingFloatData) :
 
     private var incomingView: IncomingView = IncomingView(context)
 
-    private val show: Boolean = true
-
     private var callStatusObserver = Observer<TUICallDefine.Status> {
         if (it == TUICallDefine.Status.None || it == TUICallDefine.Status.Accept) {
             cancelIncomingView()
@@ -52,7 +49,7 @@ class InComingFloatView(floatData: InComingFloatData) :
     }
 
     override fun showIncomingView(user: User) {
-        Log.d(TAG_CALL_INCOMING_VIEW, "AppInComingFloatView.showIncomingView, user:${user.id}")
+        Log.d(TAG_CALL_INCOMING_VIEW, "InComingFloatView.showIncomingView, user:${user.id}")
         incomingView.showIncomingView(user)
         addObserver()
         WindowManagerProxy.getWindowManager().addView(this)
@@ -109,7 +106,7 @@ class InComingFloatView(floatData: InComingFloatData) :
     }
 
     override fun cancelIncomingView() {
-        Log.d(TAG_CALL_INCOMING_VIEW, "AppInComingFloatView.cancelIncomingView")
+        Log.d(TAG_CALL_INCOMING_VIEW, "InComingFloatView.cancelIncomingView")
         incomingView.cancelIncomingView()
         if (isAttachedToWindow) {
             WindowManagerProxy.getWindowManager().removeView(this)

+ 1 - 1
module/call/src/main/java/com/adealink/weparty/call/view/floatview/IncomingCallReceiver.kt → module/call/src/main/java/com/adealink/weparty/call/view/floatview/incoming/IncomingCallReceiver.kt

@@ -1,4 +1,4 @@
-package com.adealink.weparty.call.view.floatview
+package com.adealink.weparty.call.view.floatview.incoming
 
 import android.content.BroadcastReceiver
 import android.content.Context

+ 1 - 2
module/call/src/main/java/com/adealink/weparty/call/view/floatview/IncomingNotificationView.kt → module/call/src/main/java/com/adealink/weparty/call/view/floatview/incoming/IncomingNotificationView.kt

@@ -1,4 +1,4 @@
-package com.adealink.weparty.call.view.floatview
+package com.adealink.weparty.call.view.floatview.incoming
 
 import android.app.Notification
 import android.app.NotificationManager
@@ -18,7 +18,6 @@ import com.adealink.weparty.call.CallActivity
 import com.adealink.weparty.call.R
 import com.adealink.weparty.call.constant.TAG_CALL_INCOMING_VIEW
 import com.adealink.weparty.call.util.getNotificationCallWaitingTips
-import com.adealink.weparty.call.view.IInComing
 import com.adealink.weparty.commonui.ext.dp
 import com.adealink.weparty.module.profile.data.UserInfo
 import com.adealink.weparty.notifiation.CALL_NOTIFICATION_CHANNEL_ID

+ 1 - 1
module/call/src/main/java/com/adealink/weparty/call/view/floatview/IncomingView.kt → module/call/src/main/java/com/adealink/weparty/call/view/floatview/incoming/IncomingView.kt

@@ -1,4 +1,4 @@
-package com.adealink.weparty.call.view.floatview
+package com.adealink.weparty.call.view.floatview.incoming
 
 import android.content.Context
 import android.content.Intent

+ 2 - 0
module/call/src/main/java/com/tencent/qcloud/tuikit/tuicallkit/data/Constants.kt

@@ -6,6 +6,8 @@ object Constants {
     const val MAX_USER = 9
     const val EVENT_TUICALLKIT_CHANGED = "eventTUICallKitChanged"
     const val EVENT_START_INCOMING_VIEW = "eventStartIncomingView"
+    const val EVENT_START_CALLING_VIEW = "eventStartCallingView"
+    const val EVENT_DISMISS_CALLING_VIEW = "eventDismissCallingView"
 
     const val EVENT_VIEW_STATE_CHANGED = "eventViewStateChanged"
     const val EVENT_SHOW_FULL_VIEW = "eventShowFullView"

+ 47 - 68
module/call/src/main/java/com/tencent/qcloud/tuikit/tuicallkit/internal/ServiceInitializer.kt

@@ -1,32 +1,32 @@
 package com.tencent.qcloud.tuikit.tuicallkit.internal
 
 import android.app.Activity
-import android.app.Application
 import android.content.ContentProvider
 import android.content.ContentValues
 import android.content.Context
 import android.database.Cursor
 import android.net.Uri
-import android.os.Bundle
 import com.adealink.frame.log.Log
+import com.adealink.frame.router.Router
+import com.adealink.frame.util.ActivityLifecycleCallbacksExt
+import com.adealink.frame.util.AppUtil
 import com.adealink.weparty.call.CallActivity
 import com.adealink.weparty.call.WenextUICallKitImpl
 import com.adealink.weparty.call.constant.TAG_CALL
-import com.tencent.cloud.tuikit.engine.call.TUICallDefine
+import com.adealink.weparty.call.constant.TAG_CALL_FLOW
+import com.adealink.weparty.commonui.widget.floatview.WindowManagerProxy
+import com.adealink.weparty.module.call.Call
+import com.adealink.weparty.widget.floatview.FloatViewFactory
 import com.tencent.qcloud.tuicore.TUIConstants
 import com.tencent.qcloud.tuicore.TUICore
 import com.tencent.qcloud.tuicore.TUILogin
-import com.tencent.qcloud.tuicore.permission.PermissionRequester
-import com.tencent.qcloud.tuikit.tuicallkit.state.TUICallState
-import com.tencent.qcloud.tuikit.tuicallkit.utils.DeviceUtils
-import com.tencent.qcloud.tuikit.tuicallkit.view.component.floatview.FloatWindowService
-import com.tencent.qcloud.tuikit.tuicallkit.view.component.floatview.FloatingWindowView
+import com.tencent.qcloud.tuikit.tuicallkit.data.Constants
 
 /**
  * `TUICallKit` uses `ContentProvider` to be registered with `TUICore`.
  * (`TUICore` is the connection and communication class of each component)
  */
-class ServiceInitializer : ContentProvider() {
+class ServiceInitializer : ContentProvider(), ActivityLifecycleCallbacksExt {
     fun init(context: Context?) {
         val callingService: TUICallKitService = TUICallKitService.sharedInstance(context!!)
         TUICore.registerService(TUIConstants.TUICalling.SERVICE_NAME, callingService)
@@ -34,47 +34,48 @@ class ServiceInitializer : ContentProvider() {
         val audioRecordService = TUIAudioMessageRecordService(context)
         TUICore.registerService(TUIConstants.TUICalling.SERVICE_NAME_AUDIO_RECORD, audioRecordService)
 
-        if (context is Application) {
-            context.registerActivityLifecycleCallbacks(object : Application.ActivityLifecycleCallbacks {
-                private var foregroundActivities = 0
-                private var isChangingConfiguration = false
-                override fun onActivityCreated(activity: Activity, bundle: Bundle?) {}
-                override fun onActivityStarted(activity: Activity) {
-                    if (isMiPushActivity(activity)) {
-                        return
-                    }
-
-                    foregroundActivities++
-                    if (foregroundActivities == 1 && !isChangingConfiguration) {
-                        //  The Call page exits the background and re-enters without repeatedly pulling up the page.
-                        if (TUILogin.isUserLogined()
-                            && activity !is CallActivity
-                            && !DeviceUtils.isServiceRunning(context, FloatWindowService::class.java.name)
-                        ) {
-                            WenextUICallKitImpl.createInstance(context).queryOfflineCall()
-                        }
-                    }
-                    isChangingConfiguration = false
-                }
+        AppUtil.registerActivityLifecycleCallbacks(this)
+    }
 
-                override fun onActivityResumed(activity: Activity) {}
-                override fun onActivityPaused(activity: Activity) {}
-                override fun onActivityStopped(activity: Activity) {
-                    if (isMiPushActivity(activity)) {
-                        return
-                    }
-                    foregroundActivities--
-                    isChangingConfiguration = activity.isChangingConfigurations
+    override fun onActivityResumed(activity: Activity) {
+        super.onActivityResumed(activity)
+        handleOfflineCall(activity)
+        handleCallingFloatView(activity)
+    }
 
-                    if (foregroundActivities == 0 && !isChangingConfiguration) {
-                        checkToShowFloatWindow(context)
-                    }
-                }
+    /**
+     * 处理
+     */
+    private fun handleCallingFloatView(activity: Activity) {
+        Log.d(TAG_CALL_FLOW, "handleCallingFloatView(onActivityResumed)")
+        if (isMiPushActivity(activity)) {
+            return
+        }
+        val callActivity = Router.getClazz(Call.Call.PATH)?.name
+        if (!callActivity.isNullOrEmpty() && callActivity == activity::class.java.name) {
+            //当前在呼叫页面
+            TUICore.notifyEvent(Constants.EVENT_TUICALLKIT_CHANGED, Constants.EVENT_DISMISS_CALLING_VIEW, HashMap())
+        } else {
+            TUICore.notifyEvent(Constants.EVENT_TUICALLKIT_CHANGED, Constants.EVENT_START_CALLING_VIEW, HashMap())
+        }
+    }
 
-                override fun onActivitySaveInstanceState(activity: Activity, outState: Bundle) {}
-                override fun onActivityDestroyed(activity: Activity) {}
-            })
+    /**
+     * 处理后台离线消息
+     */
+    private fun handleOfflineCall(activity: Activity) {
+        Log.d(TAG_CALL_FLOW, "handleOfflineCall(onActivityResumed)")
+        val activityCount = AppUtil.getCurrentActivityCount()
+        if (activityCount == 1) {
+            //只打开了一个Activity,即首页
+            if (TUILogin.isUserLogined()
+                && activity !is CallActivity
+                && WindowManagerProxy.getWindowManager().isFloatViewAdded(FloatViewFactory.CALL_1V1_CALLING)
+            ) {
+                WenextUICallKitImpl.createInstance(AppUtil.appContext).queryOfflineCall()
+            }
         }
+
     }
 
     private fun isMiPushActivity(activity: Activity): Boolean {
@@ -87,28 +88,6 @@ class ServiceInitializer : ContentProvider() {
         return false
     }
 
-    private fun checkToShowFloatWindow(context: Context) {
-        if (TUICallDefine.Status.None == TUICallState.instance.selfUser.get().callStatus.get()) {
-            return
-        }
-
-        if (!PermissionRequester.newInstance(PermissionRequester.FLOAT_PERMISSION).has()) {
-            return
-        }
-
-        if (DeviceUtils.isServiceRunning(context, FloatWindowService::class.java.name)) {
-            return
-        }
-
-        if (TUICallState.instance.scene.get() == TUICallDefine.Scene.GROUP_CALL) {
-            return
-            //FloatWindowService.startFloatService(FloatingWindowGroupView(context.applicationContext))
-        }
-        TUICallState.instance.isShowFloatView.set(true)
-        FloatWindowService.startFloatService(FloatingWindowView(context.applicationContext))
-        CallActivity.finishActivity()
-    }
-
     override fun onCreate(): Boolean {
         val appContext = context!!.applicationContext
         init(appContext)

+ 20 - 43
module/call/src/main/java/com/tencent/qcloud/tuikit/tuicallkit/manager/EngineManager.kt

@@ -14,13 +14,15 @@ import com.adealink.weparty.call.constant.CALL_KIT_ERROR_101008
 import com.adealink.weparty.call.constant.CALL_KIT_ERROR_101050
 import com.adealink.weparty.call.constant.TAG_CALL_ENGINE
 import com.adealink.weparty.call.data.CallUserData
+import com.adealink.weparty.call.view.floatview.calling.CallingFloatData
+import com.adealink.weparty.call.view.floatview.calling.CallingFloatView
+import com.adealink.weparty.commonui.widget.floatview.data.IBaseFloatData
 import com.tencent.cloud.tuikit.engine.call.TUICallDefine
 import com.tencent.cloud.tuikit.engine.call.TUICallDefine.CallParams
 import com.tencent.cloud.tuikit.engine.call.TUICallEngine
 import com.tencent.cloud.tuikit.engine.common.TUICommonDefine
 import com.tencent.cloud.tuikit.engine.common.TUIVideoView
 import com.tencent.imsdk.BaseConstants
-import com.tencent.qcloud.tuicore.ServiceInitializer
 import com.tencent.qcloud.tuicore.TUIConfig
 import com.tencent.qcloud.tuicore.TUIConstants
 import com.tencent.qcloud.tuicore.TUICore
@@ -35,8 +37,6 @@ import com.tencent.qcloud.tuikit.tuicallkit.state.TUICallState
 import com.tencent.qcloud.tuikit.tuicallkit.utils.PermissionRequest
 import com.tencent.qcloud.tuikit.tuicallkit.utils.PermissionRequest.requestPermissions
 import com.tencent.qcloud.tuikit.tuicallkit.utils.UserInfoUtils
-import com.tencent.qcloud.tuikit.tuicallkit.view.component.floatview.FloatWindowService
-import com.tencent.qcloud.tuikit.tuicallkit.view.component.floatview.FloatingWindowView
 import org.json.JSONException
 import org.json.JSONObject
 import java.util.Collections
@@ -312,50 +312,27 @@ class EngineManager private constructor(context: Context) {
         })
     }
 
-    fun showFloatWindow() {
-        Log.d(TAG_CALL_ENGINE, "showFloatWindow")
+    fun showCallingFloatWindow() {
+        Log.d(TAG_CALL_ENGINE, "showCallingFloatWindow")
         if (TUICallState.instance.scene.get() == TUICallDefine.Scene.GROUP_CALL) {
             return
         }
-        PermissionRequest.requestFloatPermission(ServiceInitializer.getAppContext(), object : PermissionCallback() {
-            override fun onGranted() {
-                TUICallState.instance.isShowFloatView.set(true)
-                FloatWindowService.startFloatService(FloatingWindowView(context.applicationContext))
-                CallActivity.finishActivity()
-            }
-        })
-    }
-
-    fun inviteUser(userIdList: List<String?>?) {
-        TODO("暂不支持")
-//        val params = CallParams()
-//        params.offlinePushInfo = OfflinePushInfoConfig.createOfflinePushInfo(context)
-//        params.timeout = Constants.SIGNALING_MAX_TIME
-//        TUICallEngine.createInstance(context)
-//            .inviteUser(userIdList, params, object : ValueCallback<List<String>> {
-//                override fun onSuccess(data: List<String>) {
-//                    val userList = data
-//                    Log.d(TAG_CALL_ENGINE, "inviteUsersToGroupCall success, list:$userList")
-//                    UserInfoUtils.getUserListInfo(userList, object : ValueCallback<List<User>?> {
-//                        override fun onSuccess(data: List<User>?) {
-//                            if (data.isNullOrEmpty()) {
-//                                Log.e(TAG_CALL_ENGINE, "getUsersInfo onSuccess list = null")
-//                                return
-//                            }
-//                            for (info in data) {
-//                                info.callStatus.set(TUICallDefine.Status.Waiting)
-//                                TUICallState.instance.remoteUserList.add(info)
-//                            }
-//                        }
-//
-//                        override fun onError(errCode: Int, errMsg: String?) {
-//                            Log.e(TAG_CALL_ENGINE, "getUsersInfo onError errorCode = $errCode , errorMsg = $errMsg")
-//                        }
-//                    })
-//                }
+        //当前不做全局浮窗,只做应用内浮窗
+        CallingFloatView(CallingFloatData(IBaseFloatData.MODE_APPLICATION)).showCallingView()
+        CallActivity.finishActivity()
+
+//        PermissionRequest.requestFloatPermission(ServiceInitializer.getAppContext(), object : PermissionCallback() {
+//            override fun onGranted() {
+//                CallingFloatView(CallingFloatData(IBaseFloatData.MODE_SYSTEM)).showCallingView()
+//                CallActivity.finishActivity()
+//            }
 //
-//                override fun onError(errCode: Int, errMsg: String) {}
-//            })
+//            override fun onDenied() {
+//                super.onDenied()
+//                CallingFloatView(CallingFloatData(IBaseFloatData.MODE_APPLICATION)).showCallingView()
+//                CallActivity.finishActivity()
+//            }
+//        })
     }
 
     private fun initAudioPlayDevice() {

+ 1 - 1
module/call/src/main/java/com/tencent/qcloud/tuikit/tuicallkit/state/TUICallState.kt

@@ -304,7 +304,7 @@ class TUICallState {
         }
 
         override fun onUserVoiceVolumeChanged(volumeMap: Map<String?, Int?>?) {
-            Log.d(TAG_CALL_FLOW, "onUserVoiceVolumeChanged, $volumeMap")
+            //Log.d(TAG_CALL_FLOW, "onUserVoiceVolumeChanged, $volumeMap")
             if (volumeMap.isNullOrEmpty()) {
                 return
             }

+ 0 - 231
module/call/src/main/java/com/tencent/qcloud/tuikit/tuicallkit/view/component/floatview/FloatWindowService.kt

@@ -1,231 +0,0 @@
-package com.tencent.qcloud.tuikit.tuicallkit.view.component.floatview
-
-import android.animation.ValueAnimator
-import android.app.Service
-import android.content.Intent
-import android.content.res.Configuration
-import android.graphics.PixelFormat
-import android.os.Binder
-import android.os.Build
-import android.os.IBinder
-import android.view.Gravity
-import android.view.MotionEvent
-import android.view.View
-import android.view.WindowManager
-import com.adealink.frame.log.Log
-import com.adealink.frame.router.Router
-import com.adealink.weparty.call.CallActivity
-import com.adealink.weparty.call.constant.TAG_CALL_FLOAT_WINDOW
-import com.adealink.weparty.module.call.Call
-import com.tencent.cloud.tuikit.engine.call.TUICallDefine
-import com.tencent.qcloud.tuicore.ServiceInitializer
-import com.tencent.qcloud.tuicore.TUICore
-import com.tencent.qcloud.tuicore.util.ScreenUtil
-import com.tencent.qcloud.tuikit.tuicallkit.data.Constants
-import com.tencent.qcloud.tuikit.tuicallkit.state.TUICallState
-import com.tencent.qcloud.tuikit.tuicallkit.view.root.BaseCallView
-
-class FloatWindowService : Service() {
-    private var windowManager: WindowManager? = null
-    private var windowLayoutParams: WindowManager.LayoutParams? = null
-    private var screenWidth = 0
-    private var callViewWidth = 0
-    private var touchStartX = 0
-    private var touchStartY = 0
-    private var touchCurrentX = 0
-    private var touchCurrentY = 0
-    private var startX = 0
-    private var startY = 0
-    private var stopX = 0
-    private var stopY = 0
-    private var isMove = false
-
-    companion object {
-        private var callView: BaseCallView? = null
-
-        fun startFloatService(view: BaseCallView) {
-            Log.i(TAG_CALL_FLOAT_WINDOW, "startFloatService, view: $callView")
-            this.callView = view
-            this.callView?.setOnClickListener {
-                stopService()
-                if (TUICallState.instance.selfUser.get().callStatus.get() != TUICallDefine.Status.None) {
-                    val context = ServiceInitializer.getAppContext()
-                    Router.build(context, Call.Call.PATH)
-                        .setFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
-                        .start()
-                }
-            }
-            val serviceIntent = Intent(ServiceInitializer.getAppContext(), FloatWindowService::class.java)
-            ServiceInitializer.getAppContext().startService(serviceIntent)
-        }
-
-        fun stopService() {
-            Log.i(TAG_CALL_FLOAT_WINDOW, "stopService")
-            TUICallState.instance.isShowFloatView.set(false)
-            if (callView != null) {
-                callView?.clear()
-            }
-            val serviceIntent = Intent(ServiceInitializer.getAppContext(), FloatWindowService::class.java)
-            ServiceInitializer.getAppContext().stopService(serviceIntent)
-        }
-    }
-
-    override fun onCreate() {
-        super.onCreate()
-        initWindow()
-    }
-
-    override fun onConfigurationChanged(newConfig: Configuration) {
-        super.onConfigurationChanged(newConfig)
-        if (callView == null || windowLayoutParams == null || windowManager == null) {
-            return
-        }
-        windowLayoutParams?.x = 0
-        val screenWidth = ScreenUtil.getScreenWidth(applicationContext)
-        val screenHeight = ScreenUtil.getScreenHeight(applicationContext)
-        windowLayoutParams?.y = if (screenWidth > screenHeight) {
-            (screenHeight - callView!!.height) / 2
-        } else {
-            ScreenUtil.dip2px(100f)
-        }
-        callView?.let { windowManager?.updateViewLayout(it, windowLayoutParams) }
-    }
-
-    override fun onBind(intent: Intent): IBinder {
-        return FloatBinder()
-    }
-
-    override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int {
-        return START_NOT_STICKY
-    }
-
-    override fun onDestroy() {
-        super.onDestroy()
-        if (null != callView && callView!!.isAttachedToWindow) {
-            windowManager?.removeView(callView)
-        }
-        callView = null
-    }
-
-    private fun initWindow() {
-        windowManager = applicationContext.getSystemService(WINDOW_SERVICE) as WindowManager
-        windowLayoutParams = viewParams
-        screenWidth = ScreenUtil.getScreenWidth(applicationContext)
-        if (null != callView) {
-            Log.i(TAG_CALL_FLOAT_WINDOW, "startFloatService, addView: $callView")
-            windowManager!!.addView(callView, windowLayoutParams)
-            TUICore.notifyEvent(Constants.EVENT_VIEW_STATE_CHANGED, Constants.EVENT_SHOW_FLOAT_VIEW, HashMap())
-            callView!!.setOnTouchListener(FloatingListener())
-        }
-    }
-
-    private val viewParams: WindowManager.LayoutParams
-        private get() {
-            windowLayoutParams = WindowManager.LayoutParams()
-            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
-                windowLayoutParams!!.type = WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY
-            } else {
-                windowLayoutParams!!.type = WindowManager.LayoutParams.TYPE_PHONE
-            }
-            windowLayoutParams!!.flags = (WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL
-                    or WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
-                    or WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS)
-            windowLayoutParams!!.gravity = Gravity.END or Gravity.TOP
-            windowLayoutParams!!.x = 10
-            windowLayoutParams!!.y = ScreenUtil.dip2px(100f)
-            windowLayoutParams!!.width = WindowManager.LayoutParams.WRAP_CONTENT
-            windowLayoutParams!!.height = WindowManager.LayoutParams.WRAP_CONTENT
-            windowLayoutParams!!.format = PixelFormat.TRANSPARENT
-            return windowLayoutParams as WindowManager.LayoutParams
-        }
-
-    inner class FloatBinder : Binder() {
-        val service: FloatWindowService
-            get() = this@FloatWindowService
-    }
-
-    inner class FloatingListener : View.OnTouchListener {
-        override fun onTouch(v: View, event: MotionEvent): Boolean {
-            val action = event.action
-            when (action) {
-                MotionEvent.ACTION_DOWN -> {
-                    isMove = false
-                    touchStartX = event.rawX.toInt()
-                    touchStartY = event.rawY.toInt()
-                    startX = event.rawX.toInt()
-                    startY = event.rawY.toInt()
-                }
-
-                MotionEvent.ACTION_MOVE -> {
-                    touchCurrentX = event.rawX.toInt()
-                    touchCurrentY = event.rawY.toInt()
-                    if (windowLayoutParams != null && null != callView) {
-                        windowLayoutParams!!.x += touchStartX - touchCurrentX
-                        windowLayoutParams!!.y += touchCurrentY - touchStartY
-                        windowManager!!.updateViewLayout(callView, windowLayoutParams)
-                    }
-                    touchStartX = touchCurrentX
-                    touchStartY = touchCurrentY
-                }
-
-                MotionEvent.ACTION_UP -> {
-                    stopX = event.rawX.toInt()
-                    stopY = event.rawY.toInt()
-                    if (Math.abs(startX - stopX) >= 5 || Math.abs(startY - stopY) >= 5) {
-                        isMove = true
-                        if (null != callView) {
-                            callViewWidth = callView!!.width
-                            if (touchCurrentX < screenWidth / 2) {
-                                startScroll(screenWidth - callViewWidth, stopX, false)
-                            } else {
-                                startScroll(0, stopX, true)
-                            }
-                        }
-                    }
-                }
-
-                else -> {}
-            }
-            return isMove
-        }
-    }
-
-    private fun startScroll(start: Int, end: Int, isLeft: Boolean) {
-        val valueAnimator = ValueAnimator.ofFloat(start.toFloat(), end.toFloat()).setDuration(300)
-        valueAnimator.addUpdateListener(ValueAnimator.AnimatorUpdateListener { animation ->
-            if (windowLayoutParams == null || callView == null) {
-                return@AnimatorUpdateListener
-            }
-            callViewWidth = callView!!.width
-            if (isLeft) {
-                windowLayoutParams!!.x = (start * (1 - animation.animatedFraction)).toInt()
-            } else {
-                val end = (screenWidth - start - callViewWidth) * animation.animatedFraction
-                windowLayoutParams!!.x = (start + end).toInt()
-            }
-            if (windowLayoutParams!!.x > screenWidth - callViewWidth) {
-                windowLayoutParams!!.x = screenWidth - callViewWidth
-            }
-            calculateHeight()
-            windowManager!!.updateViewLayout(callView, windowLayoutParams)
-        })
-        valueAnimator.start()
-    }
-
-    private fun calculateHeight() {
-        if (windowLayoutParams == null) {
-            return
-        }
-        val height = callView!!.height
-        val screenHeight = ScreenUtil.getScreenHeight(applicationContext)
-        val resourceId = ServiceInitializer.getAppContext().resources
-            .getIdentifier("status_bar_height", "dimen", "android")
-        val statusBarHeight = ServiceInitializer.getAppContext().resources.getDimensionPixelSize(resourceId)
-        if (windowLayoutParams!!.y < 0) {
-            windowLayoutParams!!.y = 0
-        } else if (windowLayoutParams!!.y > screenHeight - height - statusBarHeight) {
-            windowLayoutParams!!.y = screenHeight - height - statusBarHeight
-        }
-    }
-
-}

+ 0 - 5
module/call/src/main/java/com/tencent/qcloud/tuikit/tuicallkit/viewmodel/component/floatview/FloatingWindowViewModel.kt

@@ -3,7 +3,6 @@ package com.tencent.qcloud.tuikit.tuicallkit.viewmodel.component.floatview
 import com.tencent.cloud.tuikit.engine.call.TUICallDefine
 import com.tencent.qcloud.tuikit.tuicallkit.data.User
 import com.tencent.qcloud.tuikit.tuicallkit.state.TUICallState
-import com.tencent.qcloud.tuikit.tuicallkit.view.component.floatview.FloatWindowService
 import com.trtc.tuikit.common.livedata.LiveData
 
 class FloatingWindowViewModel {
@@ -32,8 +31,4 @@ class FloatingWindowViewModel {
             remoteUser
         }
     }
-
-    fun stopFloatService() {
-        FloatWindowService.stopService()
-    }
 }

+ 6 - 4
module/call/src/main/res/values-ar/strings.xml

@@ -32,8 +32,8 @@
     <string name="call_have_a_new_call">لديك مكالمة جديدة</string>
     <string name="call_have_a_new_audio_call_cost">دعوة محادثة صوتية، بتكلفة %s عملة/دقيقة بعد الاتصال</string>
     <string name="call_have_a_new_audio_call_earn">دعوة محادثة صوتية، احصل على %s ماسة/15 ثانية بعد الاتصال</string>
-    <string name="call_have_a_new_video_call_cost">دعوة محادثة صوتية، تكلفة %s عملة/دقيقة بعد الاتصال</string>
-    <string name="call_have_a_new_video_call_earn">دعوة للدردشة الصوتية، احصل على %s ماسة/15 ثانية بعد الاتصال</string>
+    <string name="call_have_a_new_video_call_cost">دعوة محادثة فيديو، بتكلفة %s عملة/دقيقة بعد الاتصال</string>
+    <string name="call_have_a_new_video_call_earn">دعوة محادثة فيديو، احصل على %s ماسة/15 ثانية بعد الاتصال</string>
     <string name="call_error_in_peer_blacklist">المُعرّف مُدرج في القائمة السوداء. تعذّر إرسال هذه الرسالة!</string>
     <string name="call_error_invalid_login">تسجيل الدخول غير صالح، يرجى تسجيل الدخول مرة أخرى</string>
     <string name="call_error_parameter_invalid">خطأ في المعلمة</string>
@@ -44,8 +44,8 @@
     <string name="call_chat_called_waiting_tips">لقد تمت دعوتك إلى مكالمة صوتية</string>
     <string name="call_chat_caller_cost">دعوة محادثة صوتية، التكلفة %s[icon]/دقيقة بعد الاتصال</string>
     <string name="call_chat_called_earn">دعوة محادثة صوتية، احصل على %s[icon]/15s بعد الاتصال</string>
-    <string name="call_video_caller_cost">دعوة محادثة صوتية، التكلفة %s[icon]/دقيقة بعد الاتصال</string>
-    <string name="call_video_called_earn">دعوة للدردشة الصوتية، احصل على %s[icon]/15s بعد الاتصال</string>
+    <string name="call_video_caller_cost">دعوة محادثة فيديو، التكلفة %s[icon]/دقيقة بعد الاتصال</string>
+    <string name="call_video_called_earn">دعوة محادثة فيديو، احصل على %s[icon]/15s بعد الاتصال</string>
     <string name="call_video_invitation">دعوة فيديو</string>
     <string name="call_video_invitation_tips">احصل على %s من الماس [icon]/15 ثانية</string>
     <string name="call_video_calling">مكالمات الفيديو</string>
@@ -63,4 +63,6 @@
     <string name="call_permission_grant_fail">فشل منح الإذن</string>
     <string name="call_kit_error">خطأ الخادم(%s)</string>
     <string name="call_kit_error_already_in_call">لا يمكن بدء المكالمة، وهي قيد المكالمة بالفعل</string>
+    <string name="call_caller_wait">نداء…</string>
+    <string name="call_called_wait">في انتظار الجواب…</string>
 </resources>

+ 6 - 4
module/call/src/main/res/values-zh/strings.xml

@@ -32,8 +32,8 @@
     <string name="call_have_a_new_call">您有新来电</string>
     <string name="call_have_a_new_audio_call_cost">语音聊天邀请,连接后每分钟花费 %s 币</string>
     <string name="call_have_a_new_audio_call_earn">语音聊天邀请,连接后15秒获得%s钻石</string>
-    <string name="call_have_a_new_video_call_cost">语音聊天邀请,连接后每分钟花费 %s 币</string>
-    <string name="call_have_a_new_video_call_earn">语音聊天邀请,连接后15秒获得%s钻石</string>
+    <string name="call_have_a_new_video_call_cost">视频聊天邀请,连接后每分钟花费 %s 币</string>
+    <string name="call_have_a_new_video_call_earn">视频聊天邀请,连接后15秒获得%s钻石</string>
     <string name="call_error_in_peer_blacklist">该标识符已列入黑名单。无法发送该消息!</string>
     <string name="call_error_invalid_login">登录无效,请重新登录</string>
     <string name="call_error_parameter_invalid">参数错误</string>
@@ -44,8 +44,8 @@
     <string name="call_chat_called_waiting_tips">您受邀参加语音通话</string>
     <string name="call_chat_caller_cost">语音聊天邀请,连接后花费 %s[icon]/分钟</string>
     <string name="call_chat_called_earn">语音聊天邀请,连接后 15 秒获取 %s[icon]</string>
-    <string name="call_video_caller_cost">语音聊天邀请,连接后花费 %s[icon]/分钟</string>
-    <string name="call_video_called_earn">语音聊天邀请,连接后15秒获取%s[icon]</string>
+    <string name="call_video_caller_cost">视频聊天邀请,连接后花费 %s[icon]/分钟</string>
+    <string name="call_video_called_earn">视频聊天邀请,连接后15秒获取%s[icon]</string>
     <string name="call_video_invitation">视频邀请</string>
     <string name="call_video_invitation_tips">每 15 秒获得 %s 颗钻石 [icon]</string>
     <string name="call_video_calling">视频通话</string>
@@ -63,4 +63,6 @@
     <string name="call_permission_grant_fail">权限授予失败</string>
     <string name="call_kit_error">服务错误(%s)</string>
     <string name="call_kit_error_already_in_call">呼叫失败,已经在呼叫中</string>
+    <string name="call_caller_wait">呼叫中…</string>
+    <string name="call_called_wait">等待接听…</string>
 </resources>

+ 2 - 0
module/call/src/main/res/values/dimens.xml

@@ -7,4 +7,6 @@
     <dimen name="call_video_small_view_width">90dp</dimen>
     <dimen name="call_video_small_view_height">160dp</dimen>
 
+    <dimen name="call_calling_float_view_width">90dp</dimen>
+
 </resources>

+ 6 - 4
module/call/src/main/res/values/strings.xml

@@ -32,8 +32,8 @@
     <string name="call_have_a_new_call">You have a new call</string>
     <string name="call_have_a_new_audio_call_cost">Audio chat invitation, cost %s coin/min after connection</string>
     <string name="call_have_a_new_audio_call_earn">Audio chat invitation, get %s diamond/15s after connection</string>
-    <string name="call_have_a_new_video_call_cost">Voice chat invitation, cost %s coin/min after connection</string>
-    <string name="call_have_a_new_video_call_earn">Voice chat invitation, get %s diamond/15s after connection</string>
+    <string name="call_have_a_new_video_call_cost">Video chat invitation, cost %s coin/min after connection</string>
+    <string name="call_have_a_new_video_call_earn">Video chat invitation, get %s diamond/15s after connection</string>
     <string name="call_error_in_peer_blacklist">The identifier is in blacklist. Failed to send this message!</string>
     <string name="call_error_invalid_login">Invalid login, please login again</string>
     <string name="call_error_parameter_invalid">Parameter error</string>
@@ -44,8 +44,8 @@
     <string name="call_chat_called_waiting_tips">You are invited to a voice call</string>
     <string name="call_chat_caller_cost">Audio chat invitation, cost %s[icon]/min after connection</string>
     <string name="call_chat_called_earn">Audio chat invitation, get %s[icon]/15s after connection</string>
-    <string name="call_video_caller_cost">Voice chat invitation, cost %s[icon]/min after connection</string>
-    <string name="call_video_called_earn">Voice chat invitation, get %s[icon]/15s after connection</string>
+    <string name="call_video_caller_cost">Video chat invitation, cost %s[icon]/min after connection</string>
+    <string name="call_video_called_earn">Video chat invitation, get %s[icon]/15s after connection</string>
     <string name="call_video_invitation">Video Invitation</string>
     <string name="call_video_invitation_tips">Get %s diamonds [icon]/15s</string>
     <string name="call_video_calling">Video Calling</string>
@@ -63,4 +63,6 @@
     <string name="call_permission_grant_fail">Permission grant failed</string>
     <string name="call_kit_error">Server Error(%s)</string>
     <string name="call_kit_error_already_in_call">Can not start call, already in call</string>
+    <string name="call_caller_wait">Calling…</string>
+    <string name="call_called_wait">Waiting for answer…</string>
 </resources>