This commit is contained in:
zhongchao
2021-11-05 22:59:09 +08:00
parent a4938ccd8c
commit 6c094debd8
96 changed files with 671 additions and 3266 deletions

View File

@@ -1,30 +0,0 @@
package com.mogo.chat.aspect
import org.aspectj.lang.ProceedingJoinPoint
import org.aspectj.lang.annotation.Around
import org.aspectj.lang.annotation.Aspect
import org.aspectj.lang.annotation.Pointcut
import java.util.concurrent.TimeUnit
@Aspect
class ExceptionAspectj : BaseAspectj() {
@Pointcut("execution(* com.tencent.sharp.jni.TraeAudioManager\$2.run(..))")
fun gmeTrack() {
}
@Around("gmeTrack()")
fun logExecute(joinPoint: ProceedingJoinPoint) {
try {
enterMethod(joinPoint)
val startNanos = System.nanoTime()
val result = joinPoint.proceed()
val stopNanos = System.nanoTime()
val lengthMill = TimeUnit.NANOSECONDS.toMillis(stopNanos - startNanos)
exitMethod(joinPoint, result, lengthMill)
} catch (e: Exception) {
e.printStackTrace()
}
}
}

View File

@@ -1,14 +0,0 @@
package com.mogo.chat.aspect;
import java.lang.annotation.Retention;
import java.lang.annotation.Target;
import static java.lang.annotation.ElementType.CONSTRUCTOR;
import static java.lang.annotation.ElementType.METHOD;
import static java.lang.annotation.ElementType.TYPE;
import static java.lang.annotation.RetentionPolicy.RUNTIME;
@Target({TYPE, METHOD, CONSTRUCTOR})
@Retention(RUNTIME)
public @interface PushMsg {
}

View File

@@ -1,63 +0,0 @@
package com.mogo.chat.aspect
import android.util.Log
import android.view.View
import com.mogo.chat.constant.PUSH_MSG_AGREE_ENTER
import com.mogo.chat.constant.PUSH_MSG_HANG_UP
import com.mogo.chat.model.bean.Message
import com.mogo.chat.util.isDoubleClick
import com.mogo.chat.util.sp.recordCallTime
import com.mogo.chat.util.trackHangUp
import org.aspectj.lang.JoinPoint
import org.aspectj.lang.annotation.Aspect
import org.aspectj.lang.annotation.Before
import org.aspectj.lang.annotation.Pointcut
@Aspect
class TrackAspectj {
companion object {
const val TAG = "TrackAspectj"
}
@Pointcut("execution(* android.view.View.OnClickListener.onClick(..))")
fun trackOnClick() {
}
@Before("trackOnClick()")
fun trackClick(joinPoint: JoinPoint) {
val view = joinPoint.args[0] as View
if (isDoubleClick(view.id)) {
Log.i("trackClick", "重复点击,已过滤")
return
}
}
@Pointcut("within(@com.mogo.chat.aspect.PushMsg *)")
fun withinPushClass() {
}
@Pointcut("execution(!synthetic * *(..))&& withinPushClass()")
fun methodInsidePushType() {
}
@Pointcut("execution(@com.mogo.chat.aspect.PushMsg * *(..))|| methodInsidePushType()")
fun pushMethod() {
}
@Before("pushMethod()")
fun trackPushMsg(joinPoint: JoinPoint) {
val msg = joinPoint.args[0] as Message
when (msg.status) {
PUSH_MSG_AGREE_ENTER -> {
recordCallTime()
}
PUSH_MSG_HANG_UP -> {
trackHangUp(msg.type)
}
}
}
}

View File

@@ -6,12 +6,12 @@ class HttpConstants {
companion object {
const val DEV_BASE_URL_OWNER = "http://dzt-show.zhidaohulian.com/"
const val DEV_CONFIG_URL = "http://dzt-test.zhidaohulian.com/"
const val RELEASE_BASE_URL_OWNER = "http://dzt.zhidaohulian.com/"
private const val DEV_BASE_URL_OWNER = "http://dzt-show.zhidaohulian.com/"
private const val DEV_CONFIG_URL = "http://dzt-test.zhidaohulian.com/"
private const val RELEASE_BASE_URL_OWNER = "http://dzt.zhidaohulian.com/"
const val SOCKET_SERVER = "ws://62.234.196.121:4001/ws"
const val DEV_SOCKET_SERVER = "ws://dzt-test.zhidaohulian.com/ws"
private const val SOCKET_SERVER = "ws://62.234.196.121:4001/ws"
private const val DEV_SOCKET_SERVER = "ws://dzt-test.zhidaohulian.com/ws"
fun getBaseUrl(): String {
return when (getNetMode()) {

View File

@@ -1,7 +0,0 @@
package com.mogo.chat.constant
enum class RequestCode {
MATCH_ACTIVITY,
PERSONAL_CENTER_ACTIVITY
}

View File

@@ -1,9 +0,0 @@
package com.mogo.chat.constant
enum class ResultCode {
MATCH_CANCEL,
MATCH_ENTRY_ROOM,
MATCH_FAIL,
PERSONAL_CENTER_CALL
}

View File

@@ -3,21 +3,11 @@ package com.mogo.chat.provider
import com.mogo.commons.AbsMogoApplication
import com.mogo.map.location.IMogoLocationClient
import com.mogo.module.common.MogoApisHandler
import com.mogo.service.map.IMogoMapService
import com.mogo.service.statusmanager.IMogoStatusManager
class ServiceApi {
companion object {
fun mapService(): IMogoMapService?{
return MogoApisHandler.getInstance().apis.mapServiceApi
}
fun statusManager(): IMogoStatusManager? {
return MogoApisHandler.getInstance().apis.statusManagerApi
}
fun locationClient(): IMogoLocationClient? {
return MogoApisHandler.getInstance().apis.mapServiceApi.getSingletonLocationClient(AbsMogoApplication.getApp().applicationContext)
}

View File

@@ -16,18 +16,11 @@ import com.mogo.chat.constant.HttpConstants
import com.mogo.chat.constant.SOCKET_HAND_SHAKE
import com.mogo.chat.constant.SOCKET_HEART_BEAT
import com.mogo.chat.constant.TAG
import com.mogo.chat.model.bean.Message
import com.mogo.chat.model.bean.Sns
import com.mogo.chat.model.bean.SocketMsg
import com.mogo.chat.model.bean.toSns
import com.mogo.chat.model.control.ChatController
import com.mogo.chat.util.UserInfoHelper.currentRoomId
import com.mogo.chat.util.audio.AudioFocusUtil
import com.mogo.chat.util.log
import com.mogo.chat.util.sp.getRoomId
import com.mogo.chat.util.trackAppEnter
import com.mogo.chat.window.CallingWindowManager
import com.mogo.chat.window.IWindowCallActionListener
import com.mogo.cloud.passport.MoGoAiCloudClientConfig
import com.mogo.websocket.ISocketMsgCallBack
import com.mogo.websocket.ISocketMsgSetting
@@ -36,7 +29,7 @@ import kotlinx.coroutines.GlobalScope
import kotlinx.coroutines.launch
class IMService : Service(), ICallMessage, IWindowCallActionListener {
class IMService : Service(), ICallMessage {
companion object {
@@ -45,8 +38,6 @@ class IMService : Service(), ICallMessage, IWindowCallActionListener {
}
}
private lateinit var callingWindowManager: CallingWindowManager
override fun onBind(intent: Intent): IBinder? {
return null
}
@@ -72,7 +63,6 @@ class IMService : Service(), ICallMessage, IWindowCallActionListener {
ChatController.getUserInfo()
callController.addCallBack(this.javaClass.simpleName, this)
callingWindowManager = CallingWindowManager(this, this)
// 注册状态回调,用来处理音频焦点
callTypeManager.addCallTypeChangedListener(object : ICallTypeChangedListener {
override fun onCallTypeChanged(callType: IMType) {
@@ -101,7 +91,8 @@ class IMService : Service(), ICallMessage, IWindowCallActionListener {
override fun getHeartBeatMsg(): String {
log(TAG, "getHeartBeatMsg")
val socketMsg = SocketMsg(SOCKET_HEART_BEAT, MoGoAiCloudClientConfig.getInstance().sn, getRoomId())
val socketMsg =
SocketMsg(SOCKET_HEART_BEAT, MoGoAiCloudClientConfig.getInstance().sn, getRoomId())
return Gson().toJson(socketMsg)
}
}
@@ -133,57 +124,6 @@ class IMService : Service(), ICallMessage, IWindowCallActionListener {
}
}
override fun initStatus() {
super.initStatus()
callingWindowManager.hideIncomingCall()
}
/**
* 浮窗点击接听电话
*/
override fun windowAnswerCall(userReceiver: Sns) {
trackAppEnter("7")
ChatServiceHandler.answer(userReceiver.sn, currentRoomId, {
log(TAG, "接听电话成功 ---> ")
callingWindowManager.hideIncomingCall()
ChatController.enterRoom(currentRoomId)
callController.callingReceiver()
}, {
log(TAG, "IMService answer call is error ,please try again")
})
}
/**
* 浮窗显示拒绝接听电话
*/
override fun windowRefuseCall(sns: Sns) {
ChatServiceHandler.refuseCall(sns.sn, {}, {})
callingWindowManager.hideIncomingCall()
}
/**
* 收到来电消息
* 1.如果当前已经进房,则拒绝
* 2.如果当前已经收到邀请信息,则拒绝
* 3.如果当前正在打电话中,则拒绝
*/
override fun receiverCalling(message: Message) {
super.receiverCalling(message)
if (callingWindowManager.isWindowShow) {
log(TAG, "已在通话进程中,准备拒绝他 ---> ")
ChatServiceHandler.refuseCall(message.snSender, {}, {}, message.roomId)
} else {
log(TAG, "有人打来电话,准备显示 ---> $currentRoomId")
callingWindowManager.showIncomingCall(message.toSns())
}
}
override fun refuseMatchToShowCalling(message: Message) {
super.refuseMatchToShowCalling(message)
callingWindowManager.showIncomingCall(message.toSns())
}
override fun onTrimMemory(level: Int) {
super.onTrimMemory(level)
log(TAG, "onTrimMemory ---> ")

View File

@@ -43,21 +43,7 @@ private fun track(eventType: String, data: MutableMap<String, Any>? = hashMapOf(
trackRouter!!.track(eventType, data)
}
@DebugLog
fun trackAppEnter(type: String, context: Context = AbsMogoApplication.getApp().applicationContext) {
trackNormalEvent(
TRACK_APP_ENTER,
mutableMapOf(
"from" to type,
"appname" to context.getString(R.string.app_name),
"appversion" to context.packageManager.getPackageInfo(
context.packageName,
0
).versionName
)
)
}
//todo
@DebugLog
fun trackCall(callType: Int, type: Int) {
//记录开始语音、直播时间

View File

@@ -2,10 +2,7 @@
package com.mogo.chat.util.sp
import com.mogo.chat.aspect.DebugLog
const val TEMPORARY_FILE_NAME = "temporary_im_data"
const val CONFIG_FILE_NAME = "configs_im_data"
const val FILE_NAME = "settings_im_data"
const val PARAM_ROOM_ID = "PARAM_ROOM_ID"
@@ -14,20 +11,7 @@ const val PARAM_NEW_FOCUS = "PARAM_NEW_FOCUS"
const val PARAM_VOICE_TYPE = "PARAM_VOICE_TYPE"
const val PARAM_CALL_TIME = "PARAM_CALL_TIME"
const val PARAM_INIT_TIP = "PARAM_INIT_TIP"
const val PARAM_CAR_ONLINE_STATUS = "PARAM_CAR_ONLINE_STATUS"
const val PARAM_GUIDE_SHOW_STATUS = "PARAM_GUIDE_SHOW_STATUS"
const val PARAM_CONFIG_EXPIRY_TIME = "PARAM_CONFIG_EXPIRY_TIME"
const val PARAM_CONFIG_COUNT_DOWN_TIME = "PARAM_CONFIG_COUNT_DOWN_TIME"
const val PARAM_CONFIG_VOICE_CONTENT = "PARAM_CONFIG_VOICE_CONTENT"
const val PARAM_CONFIG_IMAGE_IS_SAVED = "PARAM_CONFIG_IMAGE_IS_SAVED"
const val PARAM_CONFIG_TOPIC_GUIDE = "PARAM_CONFIG_TOPIC_GUIDE"
const val PARAM_CONFIG_FOCUS_NOTICE_TIMES = "PARAM_CONFIG_FOCUS_NOTICE_TIMES"
const val PARAM_CONFIG_OWN_NICK_NAME = "PARAM_CONFIG_OWN_NICK_NAME"
const val PARAM_CONFIG_OWN_HEAD_IMG = "PARAM_CONFIG_OWN_HEAD_IMG"
fun saveRoomId(roomId: Int) {
getCommitSP(TEMPORARY_FILE_NAME) {
@@ -86,15 +70,6 @@ fun getCarOnLineStatus(): Boolean {
return getSP(FILE_NAME).getBoolean(PARAM_CAR_ONLINE_STATUS, true)
}
fun initTip(initType: Int) {
getApplySp(FILE_NAME) {
putBoolean(PARAM_INIT_TIP + initType, true)
}
}
fun getInitStatus(initType: Int): Boolean {
return getSP(FILE_NAME).getBoolean(PARAM_INIT_TIP + initType, false)
}
fun recordCallTime() {
getApplySp(FILE_NAME) {
@@ -111,77 +86,3 @@ fun getTalkTime(): Long {
}
}
fun guideHasShown() {
getApplySp(FILE_NAME) {
putBoolean(PARAM_GUIDE_SHOW_STATUS, true).apply()
}
}
fun getGuideShowStatus(): Boolean {
return getSP(FILE_NAME).getBoolean(PARAM_GUIDE_SHOW_STATUS, false)
}
/**********************************************配置Data*****************************************************/
fun setExpiryTime(expiryTime: Long) {
getApplySp(CONFIG_FILE_NAME) {
putLong(PARAM_CONFIG_EXPIRY_TIME, expiryTime)
}
}
fun isExpiryTime(requestTime: Long): Boolean {
return getSP(CONFIG_FILE_NAME).getLong(PARAM_CONFIG_EXPIRY_TIME, 0) != requestTime
}
fun setCountDownTime(countDownTime: Int) {
getApplySp(CONFIG_FILE_NAME) {
putInt(PARAM_CONFIG_COUNT_DOWN_TIME, countDownTime)
}
}
fun getCountDownTime(): Int {
return getSP(CONFIG_FILE_NAME).getInt(PARAM_CONFIG_COUNT_DOWN_TIME, 0)
}
fun setConfigVoiceContent(voiceContent: String) {
getApplySp(CONFIG_FILE_NAME) {
putString(PARAM_CONFIG_VOICE_CONTENT, voiceContent)
}
}
fun getConfigVoiceContent(): String {
return getSP(CONFIG_FILE_NAME).getString(PARAM_CONFIG_VOICE_CONTENT, "")!!
}
fun setImageSaveStatus(saveStatus: Boolean) {
getApplySp(CONFIG_FILE_NAME) {
putBoolean(PARAM_CONFIG_IMAGE_IS_SAVED, saveStatus)
}
}
fun getImageSaveStatus(): Boolean {
return getSP(CONFIG_FILE_NAME).getBoolean(PARAM_CONFIG_IMAGE_IS_SAVED, false)
}
fun setFocusNoticeTimes(times: Int) {
getApplySp(CONFIG_FILE_NAME) {
putInt(PARAM_CONFIG_FOCUS_NOTICE_TIMES, times)
}
}
fun getFocusNoticeTimes(): Int {
return getSP(CONFIG_FILE_NAME).getInt(PARAM_CONFIG_FOCUS_NOTICE_TIMES, 0)
}
@DebugLog
fun setTopicGuideContent(content: String) {
getApplySp(CONFIG_FILE_NAME) {
putString(PARAM_CONFIG_TOPIC_GUIDE, content)
}
}
fun getTopicGuideContent(): Array<String> {
val content = getSP(CONFIG_FILE_NAME).getString(PARAM_CONFIG_TOPIC_GUIDE, "")
return if (content.isNullOrEmpty()) emptyArray() else content.split("/").toTypedArray()
}

View File

@@ -1,252 +0,0 @@
package com.mogo.chat.window
import android.content.Context
import android.graphics.PixelFormat
import android.media.AudioManager
import android.os.Build
import android.os.Handler
import android.view.Gravity
import android.view.LayoutInflater
import android.view.View
import android.view.WindowManager
import android.view.WindowManager.LayoutParams
import android.widget.ImageButton
import android.widget.ImageView
import android.widget.TextView
import com.mogo.chat.R
import com.mogo.chat.constant.TAG
import com.mogo.chat.model.bean.Sns
import com.mogo.chat.util.MediaController
import com.mogo.chat.util.log
import com.mogo.chat.voice.IMVoiceClient
import com.mogo.chat.voice.IVoiceIntentListener
import com.mogo.utils.WindowUtils
import com.mogo.utils.glide.GlideApp
/**
* 来电界面管理
*/
class CallingWindowManager(
val context: Context,
private val callActionListener: IWindowCallActionListener
) : IVoiceIntentListener {
companion object {
const val MSG_DIALING_TIME_OUT = 1001
const val DEFAULT_MAX_DIALING_TIME = 30 * 1000L
}
private var windowManager: WindowManager? = null
var isWindowShow = false
private var isShowBig = false
private var bodyView: View? = null
private var layoutParams: LayoutParams = LayoutParams()
private lateinit var userInfo: Sns
private lateinit var btnScale: ImageButton
private lateinit var ivHeadImg: ImageView
private lateinit var tvNickName: TextView
private lateinit var tvBigAnswer: TextView
private lateinit var tvBigCancel: TextView
private lateinit var ibSmallAnswer: ImageButton
private lateinit var ibSmallCancel: ImageButton
private val handler = Handler(context.mainLooper) {
log(TAG, "times up ,ready to refuse call ")
when (it.what) {
MSG_DIALING_TIME_OUT -> callActionListener.windowRefuseCall(userInfo)
}
true
}
fun showIncomingCall(userInfo: Sns) {
if (!isWindowShow) {
log(TAG, "显示来电浮窗======")
broadCastVoicePrompt()
handler.sendEmptyMessageDelayed(MSG_DIALING_TIME_OUT, DEFAULT_MAX_DIALING_TIME)
isWindowShow = true
this.userInfo = userInfo
windowManager = context.getSystemService(Context.WINDOW_SERVICE) as WindowManager
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
layoutParams.type = LayoutParams.TYPE_APPLICATION_OVERLAY
} else {
layoutParams.type = LayoutParams.TYPE_PHONE
}
layoutParams.flags = LayoutParams.FLAG_NOT_FOCUSABLE
layoutParams.gravity = Gravity.START or Gravity.TOP
layoutParams.format = PixelFormat.RGBA_8888
exchangeToBig()
}
}
private fun exchangeToBig() {
windowManager?.let {
if (bodyView != null) {
// 如果bodyView不为空需要先清除掉然后重新添加因为如果不为空则说明是从小界面切换回大界面而不是初始化展示大界面
it.removeView(bodyView)
}
bodyView =
LayoutInflater.from(context).inflate(R.layout.window_incomming_call_big, null)
layoutParams.width = LayoutParams.MATCH_PARENT
layoutParams.height = LayoutParams.MATCH_PARENT
layoutParams.x = 0
layoutParams.y = 0
initBigView()
it.addView(bodyView, layoutParams)
isShowBig = true
}
}
private fun initBigView() {
bodyView?.let {
btnScale = it.findViewById(R.id.btnScale)
ivHeadImg = it.findViewById(R.id.ivHead)
tvNickName = it.findViewById(R.id.tvUserName)
tvBigAnswer = it.findViewById(R.id.tvBigAnswer)
tvBigCancel = it.findViewById(R.id.tvBigCancel)
it.setOnClickListener(null)
GlideApp.with(context).load(userInfo.headImgUrl)
.placeholder(R.mipmap.icon_avator_big).circleCrop()
.into(ivHeadImg)
// tvNickName.text = userInfo.nickName
tvNickName.text = "云平台" //todo 需要产品后面更改逻辑,避免写死造成困扰
btnScale.setOnClickListener {
exchangeToSmall()
}
tvBigAnswer.setOnClickListener {
// 接听电话
clickDialingCall(true)
}
tvBigCancel.setOnClickListener {
// 拒绝接听电话
clickDialingCall(false)
}
}
}
private fun exchangeToSmall() {
windowManager?.let {
it.removeViewImmediate(bodyView)
bodyView =
LayoutInflater.from(context).inflate(R.layout.window_incomming_call_small, null)
val sWidth = WindowUtils.getScreenWidth(context)
val sHeight = WindowUtils.getScreenHeight(context)
val x =
sWidth - context.resources.getDimension(R.dimen.dp_580) - context.resources.getDimension(
R.dimen.dp_310
)
val y =
sHeight - context.resources.getDimension(R.dimen.dp_120) - context.resources.getDimension(
R.dimen.dp_60
) - WindowUtils.getStatusBarHeight(context)
layoutParams.width = context.resources.getDimension(R.dimen.dp_768).toInt()
layoutParams.height = context.resources.getDimension(R.dimen.dp_212).toInt()
layoutParams.gravity = Gravity.START or Gravity.TOP
layoutParams.x = x.toInt()
layoutParams.y = y.toInt()
initSmallView()
it.addView(bodyView, layoutParams)
isShowBig = false
}
}
private fun initSmallView() {
bodyView?.let {
tvNickName = it.findViewById(R.id.tvSmallUserName)
ibSmallAnswer = it.findViewById(R.id.ibSmallAnswer)
ibSmallCancel = it.findViewById(R.id.ibSmallCancel)
tvNickName.text = userInfo.nickName
it.setOnClickListener {
exchangeToBig()
}
ibSmallAnswer.setOnClickListener {
// 接听电话
callActionListener.windowAnswerCall(userInfo)
}
ibSmallCancel.setOnClickListener {
// 拒绝接听电话
callActionListener.windowRefuseCall(userInfo)
}
}
}
fun hideIncomingCall() {
log(TAG,"hideIncomingCall")
if (isWindowShow && windowManager != null) {
handler.removeMessages(MSG_DIALING_TIME_OUT)
log(TAG,"removeView : windowManager")
windowManager!!.removeView(bodyView)
windowManager = null
bodyView = null
isWindowShow = false
}
releaseAudioAndVoice()
}
/**
* 来电语音播报,现在只有语音来电,暂时不报别的
*/
private fun broadCastVoicePrompt() {
IMVoiceClient.speakAndRegisterCall({ agree ->
if (isWindowShow) {
log(TAG, "speakAndRegisterCall")
clickDialingCall(agree)
}
}, {
log(TAG, "playFinish")
playAudioCall()
registerIntentInComingCall()
})
}
private fun clickDialingCall(agree: Boolean) {
if (agree) {
callActionListener.windowAnswerCall(userInfo)
} else {
callActionListener.windowRefuseCall(userInfo)
}
releaseAudioAndVoice()
}
override fun onVoiceAnswerCall() {
callActionListener.windowAnswerCall(userInfo)
releaseAudioAndVoice()
}
override fun onVoiceRefuseCall() {
callActionListener.windowRefuseCall(userInfo)
releaseAudioAndVoice()
}
private fun releaseAudioAndVoice() {
stopAudioCall()
unRegisterVoice()
}
private fun playAudioCall() {
log(TAG, "播放来电铃声=====$isWindowShow")
if (isWindowShow) {
MediaController.startPlay(context, R.raw.call, true, AudioManager.STREAM_RING)
}
}
private fun stopAudioCall() {
log(TAG, "停止播放来电铃声======")
MediaController.release()
}
private fun registerIntentInComingCall() {
IMVoiceClient.registerIntentInComingCall(this)
}
private fun unRegisterVoice() {
IMVoiceClient.releaseSpeakAndRegisterCallback()
IMVoiceClient.unRegisterIntentInComingCall(this)
}
}

View File

@@ -1,19 +0,0 @@
package com.mogo.chat.window
import com.mogo.chat.model.bean.Sns
/**
* 浮窗通话状态通知
*/
interface IWindowCallActionListener {
/**
* 浮窗点击接听电话
*/
fun windowAnswerCall(userReceiver: Sns)
/**
* 浮窗显示拒绝接听电话
*/
fun windowRefuseCall(sns: Sns)
}