[Chat]车聊聊架构升级

This commit is contained in:
renwj
2022-03-09 11:18:30 +08:00
committed by zhongchao
parent b16e7edbd3
commit 9275ed5ff2
178 changed files with 8116 additions and 301 deletions

View File

@@ -0,0 +1,9 @@
package com.mogo.eagle.core.function.api.chat
import com.mogo.eagle.core.function.api.base.IMoGoFunctionServerProvider
import com.mogo.eagle.core.function.api.chat.biz.IMoGoChatFacade
interface IMoGoChatProvider: IMoGoFunctionServerProvider {
fun chat(): IMoGoChatFacade
}

View File

@@ -0,0 +1,13 @@
package com.mogo.eagle.core.function.api.chat.biz
class ChatConsts {
companion object{
const val TAG = "CALL_CHATTING"
const val CHAT_PROVIDER_PATH = "/callchat/provider"
const val CHAT_MODULE_NAME = "CARD_TYPE_CARS_CHATTING"
}
}

View File

@@ -0,0 +1,12 @@
package com.mogo.eagle.core.function.api.chat.biz
data class ChatParams(
val sn: String,
val carTypeName: String? = null,
val name: String? = null,
val age: Int = 0,
val sex: String = "未设置",
val iconUrl: String? = null,
val lat: Double = 0.0,
val lon: Double = 0.0,
)

View File

@@ -0,0 +1,12 @@
package com.mogo.eagle.core.function.api.chat.biz
enum class IMCallType constructor(val type: Int) {
CALL_TYPE_DEFAULT(-1),
CALL_TYPE_VOICE(0),
CALL_TYPE_VEHICLE_TEAM(3);
fun isTeam(): Boolean = this == CALL_TYPE_VEHICLE_TEAM
}

View File

@@ -0,0 +1,31 @@
package com.mogo.eagle.core.function.api.chat.biz
enum class IMType(val imType: Int) {
INIT_CALL(1000),
READY_TO_CALL_SENDER(1001),
READY_TO_CALL_RECEIVER(1002),
CALLING_SENDER(1003),
CALLING_RECEIVER(1004);
fun toText() = when (this) {
INIT_CALL -> "初始状态"
READY_TO_CALL_SENDER -> "呼叫状态"
READY_TO_CALL_RECEIVER -> "呼入状态"
CALLING_SENDER -> "通话状态-当前用户是呼叫方"
CALLING_RECEIVER -> "通话状态-当前用户是接收方"
}
}
fun IMType.isInit():Boolean{
return this == IMType.INIT_CALL
}
fun IMType.isCalling(): Boolean {
return this in IMType.CALLING_SENDER..IMType.CALLING_RECEIVER
}
fun IMType.isReadyCalling(): Boolean {
return this in IMType.READY_TO_CALL_SENDER..IMType.READY_TO_CALL_RECEIVER
}

View File

@@ -0,0 +1,204 @@
package com.mogo.eagle.core.function.api.chat.biz
import android.content.Context
import android.media.AudioManager
import com.mogo.eagle.core.data.chat.UserInfo
import kotlinx.coroutines.flow.Flow
interface IMoGoChatFacade {
/**
* 监听来电状态
* isTeam: 是否是车队类型
* user: 发送者用户数据
*/
fun onInComingCall(cb: (isTeam: Boolean, user: UserInfo) -> Unit)
/**
* 呼出方,呼出又挂断
* isTeam: 是否车队类型
* user: 发送者用户数据
*/
fun onCallingInterrupt(cb: (isTeam: Boolean, user: UserInfo) -> Unit)
/**
* 当前用户是否可以发起呼叫
*/
fun canCall(): Boolean
/**
* 当前用户是否可以收到来电
*/
fun canAnswer(): Boolean
/**
* 主动拨打电话给某人
*/
fun call(params: ChatParams): Flow<CallState>
/**
* 响应发送者通话请求
* @param sn: 发送者车机sn
*/
fun answer(sn: String): Flow<AnswerState>
/**
* 通话中,主动挂断电话
* @param sn: 接收者车机sn
* @param cb: 挂断电话后的状态回调
*/
fun handUp(sn: String): Flow<HangUpState>
/**
* 来电时,主动拒接他车通话请求
* @param sn: 发送者车机sn
* @param cb: 拒接来电状态回调
*/
fun refuse(sn: String): Flow<RefuseState>
/**
* 邀请某司机加入车队
* @param sn: 接收者车机sn
*/
fun inviteJoinVehicleTeam(sn: String): Flow<InviteState>
/**
* 加入某车队
*/
fun joinVehicleTeam(sn: String): Flow<JoinState>
/**
* 通话中,调起静音接口
* @param mute: true - 静音开启, false - 静音关闭
*/
fun muteVoice(mute: Boolean)
/**
* 音频焦点管理类
*/
fun audioFocus(): IMoGoAudioFocusFacade
/**
* 语音控制管理类
*/
fun voice(): IMoGoVoiceControlFacade
/**
* 媒体管理类
*/
fun media(): IMoGoMediaFacade
/**
* 统计相关的
*/
fun analytics(): IMoGoAnalyticsFacade
}
interface IMoGoAudioFocusFacade {
/**
* 获取音频焦点
*/
fun requireAudioFocus(onGetFocus: () -> Unit)
/**
* 释放音频焦点
*/
fun releaseAudioFocus()
}
interface IMoGoVoiceControlFacade {
/**
* 注册
*/
fun register()
/**
* 播放语音
* @param context : 当前上下文环境
* @param content : 语音播放内容
* @param listener: 语音相关回调
*/
fun speak(context: Context, content: String, listener: IMoGoVoiceCallback)
/**
* 注册车队通话免唤醒词
*/
fun registerInviteJoinTeam(context: Context, listener: IMoGoVoiceCallback)
/**
* 注册车队通话免唤醒词
*/
fun registerJoinTeam(context: Context, listener: IMoGoVoiceCallback)
/**
* 反注册车队通话免唤醒词
*/
fun unRegisterInviteJoinTeam(context: Context)
/**
* 反注册车队通话免唤醒词
*/
fun unRegisterJoinTeam(context: Context)
/**
* 注册来电免唤醒词
*/
fun registerIntentInComingCall(listener: IMoGoVoiceCallback)
/**
* 反注册来电免唤醒词
*/
fun unRegisterIntentInComingCall(context: Context)
/**
* 注册问答式免唤醒词
*/
fun speakAndRegisterCall(onCmdAgree: ((Boolean) -> Unit), onSpeakFinish: (() -> Unit), listener: IMoGoVoiceCallback)
/**
* 停止播报
*/
fun stopTTS(context: Context, text: String)
/**
* 解注册
*/
fun unRegister()
interface IMoGoVoiceCallback {
fun onVoiceCancelCall() {}
fun onVoiceInviteJoinTeam() {}
fun onVoiceJoinTeam() {}
fun onVoiceRefuseJoinTeam() {}
fun onSpeakEnd() {}
fun onVoiceAnswerCall() {}
fun onVoiceRefuseCall() {}
}
}
interface IMoGoMediaFacade {
/**
* 播放音频
*/
fun play(context: Context, audioSources: Int, isLoop: Boolean = false, channel:Int = AudioManager.STREAM_MUSIC)
/**
* 释放音频
*/
fun release()
}
interface IMoGoAnalyticsFacade {
fun track(eventType: String, data: Map<String, Any>? = hashMapOf())
}

View File

@@ -0,0 +1,555 @@
package com.mogo.eagle.core.function.api.chat.biz
import androidx.annotation.IntDef
import com.mogo.eagle.core.data.chat.socket.Message
import com.mogo.eagle.core.data.chat.socket.TeammateInfo
/**
* 呼叫状态
*/
sealed class CallState {
/**
* 呼叫开始
*/
object Init: CallState()
/**
* 接收者同意呼叫
* @param isTeam: 是否是车队成员同意
* @param msg: 同意后的下行数据
*/
class AgreeCall(val isTeam: Boolean, val msg: Message): CallState()
/**
* 接收者拒绝呼叫
* @param isTeam: 是否是车队成员同意
* @param msg: 拒绝后的下行数据
*/
class RefuseCall(val isTeam: Boolean, val msg: Message): CallState()
/**
* 发送者进房成功
*/
object EnterRoomSuccess: CallState()
/**
* 房间成员退出/进入房间
* @param isEnter: true - 进入房间; false - 退出房间
* @param hasMember: true - 除了自己是否还有成员; false - 除了自己没有其它成员
*/
class RoomMemberUpdate(val isMySelf: Boolean, val isEnter: Boolean, val members: List<TeammateInfo>? = emptyList()): CallState()
/**
* 当前用户退房成功
*/
object ExitRoomSuccess: CallState()
/**
* 对方挂断
* @param isTeam: 表示是否是车队类型
* @param msg: 下行数据
*/
class HangUp(val isTeam: Boolean, val msg: Message): CallState()
/**
* 错误状态, 业务层收到此状态要关闭呼叫页面
*/
class Error(@ErrorCode val code: Int, val msg: String, val extra: Map<String, String>? = null): CallState()
companion object {
/**
* 呼叫状态错误
*/
const val CODE_CALL_STATE_ERROR = 0
/**
* 长链接未连接
*/
const val CODE_CALL_SOCKET_DISCONNECT = 1
/**
* 关键参数不完整一般是sn参数不存在或为空
*/
const val CODE_CALL_PARAMS_INCOMPLETE = 2
/**
* 呼叫自己
*/
const val CODE_CALL_MYSELF = 3
/**
* Gme Sdk初始化失败
*/
const val CODE_GME_INIT_FAIL = 4
/**
* 获取当前用户(呼叫方)用户信息失败
*/
const val CODE_CALLER_USER_INFO_FAIL = 5
/**
* 接收方不在线
*/
const val CODE_ANSWER_OFFLINE = 6
/**
* 获取房间数据失败
*/
const val CODE_ROOM_INFO_FAIL = 7
/**
* 用户已经进房
*/
const val CODE_USER_IN_ROOM = 8
/**
* 进入房间失败
*/
const val CODE_ENTER_ROOM_FAIL = 9
/**
* 未知错误
*/
const val CODE_UNKNOWN_ERROR = 10
}
@IntDef(
CODE_CALL_STATE_ERROR,
CODE_CALL_SOCKET_DISCONNECT,
CODE_CALL_PARAMS_INCOMPLETE,
CODE_CALL_MYSELF,
CODE_GME_INIT_FAIL,
CODE_CALLER_USER_INFO_FAIL,
CODE_ANSWER_OFFLINE,
CODE_ROOM_INFO_FAIL,
CODE_USER_IN_ROOM,
CODE_ENTER_ROOM_FAIL,
CODE_UNKNOWN_ERROR
)
@Retention(AnnotationRetention.SOURCE)
annotation class ErrorCode
}
/**
* 响应状态
*/
sealed class AnswerState {
/**
* 初始状态
*/
object Init: AnswerState()
/**
* 异常状态
*/
class Error(@ErrorCode val code: Int, val msg: String, val extra: Map<String, String>? = null): AnswerState()
/**
* 应答者进房成功
*/
object EnterRoomSuccess: AnswerState()
/**
* 应答者退房成功
*/
object ExitRoomSuccess: AnswerState()
/**
* 接受车队邀请
*/
class AcceptTeamInvite(val msg: Message): AnswerState()
/**
* 拒绝车队邀请
*/
class RefuseTeamInvite(val msg: Message): AnswerState()
/**
* 房间成员退出/进入房间
* @param isMySelf: 是否是自己进出房间
* @param isEnter: true - 进入房间; false - 退出房间
* @param hasMember: true - 除了自己是否还有成员; false - 除了自己没有其它成员
*/
class RoomMemberUpdate(val isMySelf: Boolean, val isEnter: Boolean, val members: List<TeammateInfo>? = emptyList()): AnswerState()
/**
* 对方挂断
*/
class HangUp(val isTeam: Boolean, val msg: Message): AnswerState()
companion object {
/**
* 应答状态错误
*/
const val CODE_ANSWER_STATE_ERROR = -1
/**
* 长链接未连接
*/
const val CODE_ANSWER_SOCKET_DISCONNECT = -2
/**
* 应答者数据缺失, 一般是sn参数不存在或为空
*/
const val CODE_ANSWER_PARAMS_INCOMPLETE = -3
/**
* 应答自己
*/
const val CODE_ANSWER_MYSELF = -4
/**
* Gme Sdk初始化失败
*/
const val CODE_GME_INIT_FAIL = -5
/**
* 获取当前用户(应答方)用户信息失败
*/
const val CODE_ANSWER_USER_INFO_FAIL = -6
/**
* 获取呼叫方(发送方)用户信息失败
*/
const val CODE_CALLER_USER_INFO_FAIL = -7
/**
* 应答者退房失败
*/
const val CODE_ANSWER_EXIT_ROOM_FAIL = -9
/**
* 应答网络请求API失败
*/
const val CODE_ANSWER_API_REQ_FAIL = -10
/**
* 未知错误
*/
const val CODE_UNKNOWN_ERROR = -11
}
@IntDef(
CODE_ANSWER_STATE_ERROR,
CODE_ANSWER_SOCKET_DISCONNECT,
CODE_ANSWER_PARAMS_INCOMPLETE,
CODE_ANSWER_MYSELF,
CODE_GME_INIT_FAIL,
CODE_ANSWER_USER_INFO_FAIL,
CODE_CALLER_USER_INFO_FAIL,
CODE_ANSWER_EXIT_ROOM_FAIL,
CODE_ANSWER_API_REQ_FAIL
)
@Retention(AnnotationRetention.SOURCE)
annotation class ErrorCode
}
/**
* 挂断状态
*/
sealed class HangUpState {
/**
* 初始状态
*/
object Init: HangUpState()
/**
* 挂断失败
*/
class Error(@ErrorCode val code: Int, val msg: String, val extra: Map<String, String>? = null): HangUpState()
/**
* 挂断成功
*/
object Success: HangUpState()
companion object {
/**
* 挂断状态错误
*/
const val CODE_HANG_UP_STATE_ERROR = -1
/**
* 网络请求失败
*/
const val CODE_HANG_UP_API_ERROR = -2
/**
* 当前用户尚未进入房间
*/
const val CODE_HANG_UP_NOT_IN_ROOM = -3
/**
* 当前用户退出房间失败
*/
const val CODE_HANG_UP_EXIT_ROOM_ERROR = -4
/**
* 未知错误
*/
const val CODE_UNKNOWN_ERROR = -5
}
@IntDef(
CODE_HANG_UP_STATE_ERROR,
CODE_HANG_UP_API_ERROR,
CODE_HANG_UP_NOT_IN_ROOM,
CODE_HANG_UP_EXIT_ROOM_ERROR,
CODE_UNKNOWN_ERROR
)
@Retention(AnnotationRetention.SOURCE)
annotation class ErrorCode
}
/**
* 拒绝状态
*/
sealed class RefuseState {
/**
* 初始状态
*/
object Init: RefuseState()
/**
* 错误状态
*/
class Error(@ErrorCode val code: Int, val msg: String, val extra: Map<String, String>? = null): RefuseState()
/**
* 成功
*/
object Success: RefuseState()
companion object {
/**
* 拒绝状态错误
*/
const val CODE_REFUSE_STATE_ERROR = -1
/**
* 网络请求失败
*/
const val CODE_REFUSE_API_ERROR = -2
/**
* 当前用户已经进房,不能拒绝
*/
const val CODE_REFUSE_IS_IN_ROOM = -3
/**
* 未知错误
*/
const val CODE_UNKNOWN_ERROR = -4
}
@IntDef(
CODE_REFUSE_STATE_ERROR,
CODE_REFUSE_API_ERROR,
CODE_REFUSE_IS_IN_ROOM,
CODE_UNKNOWN_ERROR
)
@Retention(AnnotationRetention.SOURCE)
annotation class ErrorCode
}
/**
* 车队邀请状态
*/
sealed class InviteState {
/**
* 初始状态
*/
object Init: InviteState()
/**
* 错误状态
*/
class Error(@ErrorCode val code: Int, val msg: String, val extra: Map<String, String>? = null): InviteState()
/**
* 进房成功
*/
object EnterRoomSuccess: InviteState()
/**
* 退房成功
*/
object ExitRoomSuccess: InviteState()
/**
* 邀请被拒
*/
object Refused: InviteState()
class RoomMemberUpdate(val isMySelf: Boolean, val isEnter: Boolean, val members: List<TeammateInfo>? = emptyList()): InviteState()
companion object {
/**
* 拒绝状态错误
*/
const val CODE_INVITE_STATE_ERROR = -1
/**
* 网络请求失败
*/
const val CODE_INVITE_API_ERROR = -2
/**
* 邀请自己
*/
const val CODE_INVITE_TO_MYSELF = -3
/**
* sn不存在
*/
const val CODE_INVITE_SN_NOT_IN = -4
/**
* 用户信息请求失败
*/
const val CODE_INVITE_USR_REQ_ERROR = -5
/**
* 进入房间失败
*/
const val CODE_ENTER_ROOM_FAIL = -6
/**
* GME初始化失败
*/
const val CODE_GME_INIT_FAIL = -7
/**
* 被邀请方不在线
*/
const val CODE_INVITEE_OFFLINE = -8
/**
* 未知错误
*/
const val CODE_UNKNOWN_ERROR = -9
}
@IntDef(
CODE_INVITE_STATE_ERROR,
CODE_INVITE_API_ERROR,
CODE_INVITE_TO_MYSELF,
CODE_INVITE_SN_NOT_IN,
CODE_INVITE_USR_REQ_ERROR,
CODE_ENTER_ROOM_FAIL,
CODE_GME_INIT_FAIL
)
@Retention(AnnotationRetention.SOURCE)
annotation class ErrorCode
}
sealed class JoinState {
/**
* 初始状态
*/
object Init: JoinState()
/**
* 错误状态
*/
class Error(@ErrorCode val code: Int, val msg: String, val extra: Map<String, String>? = null): JoinState()
/**
* 进入房间成功
*/
object EnterRoomSuccess: JoinState()
/**
* 退出房间成功
*/
object ExitRoomSuccess: JoinState()
/**
* 房间成员更新
*/
class RoomMemberUpdate(val isMySelf: Boolean, val isEnter: Boolean, val members: List<TeammateInfo>? = emptyList()): JoinState()
companion object {
/**
* 网络请求失败
*/
const val CODE_JOIN_API_ERROR = -1
/**
* 用户信息请求失败
*/
const val CODE_JOIN_USR_REQ_ERROR = -2
/**
* sn不存在
*/
const val CODE_JOIN_SN_NOT_IN = -3
/**
* 加入自己
*/
const val CODE_JOIN_TO_MYSELF = -4
/**
* 当前用户状态不对
*/
const val CODE_INVITE_STATE_ERROR = -5
/**
* 长链接断开
*/
const val CODE_INVITE_STATE_SOCKET_DISCONNECT = -6
const val CODE_CALLER_USER_INFO_FAIL = -7
const val CODE_ENTER_ROOM_FAIL = -8
const val CODE_GME_INIT_FAIL = -9
/**
* 未知错误
*/
const val CODE_UNKNOWN_ERROR = -10
}
@IntDef(
CODE_JOIN_API_ERROR,
CODE_JOIN_USR_REQ_ERROR,
CODE_JOIN_SN_NOT_IN,
CODE_JOIN_TO_MYSELF,
CODE_INVITE_STATE_ERROR,
CODE_INVITE_STATE_SOCKET_DISCONNECT,
CODE_CALLER_USER_INFO_FAIL,
CODE_ENTER_ROOM_FAIL,
CODE_GME_INIT_FAIL
)
@Retention(AnnotationRetention.SOURCE)
annotation class ErrorCode
}