1
+ package io.agora.ktvapi
2
+
3
+ import android.util.Log
4
+ import io.agora.rtc2.Constants
5
+ import io.agora.rtc2.RtcEngine
6
+ import org.json.JSONObject
7
+ import java.util.HashMap
8
+
9
+ enum class ApiEventType (val value : Int ) {
10
+ API (0 ),
11
+ COST (1 ),
12
+ CUSTOM (2 )
13
+ }
14
+
15
+ object ApiEventKey {
16
+ const val TYPE = " type"
17
+ const val DESC = " desc"
18
+ const val API_VALUE = " apiValue"
19
+ const val TIMESTAMP = " ts"
20
+ const val EXT = " ext"
21
+ }
22
+
23
+ object ApiCostEvent {
24
+ const val CHANNEL_USAGE = " channelUsage" // 频道使用耗时
25
+ const val FIRST_FRAME_ACTUAL = " firstFrameActual" // 首帧实际耗时
26
+ const val FIRST_FRAME_PERCEIVED = " firstFramePerceived" // 首帧感官耗时
27
+ }
28
+
29
+ class APIReporter (
30
+ private val category : String ,
31
+ private val rtcEngine : RtcEngine
32
+ ) {
33
+ private val tag = " APIReporter"
34
+ private val messageId = " agora:scenarioAPI"
35
+ private val durationEventStartMap = HashMap <String , Long >()
36
+
37
+ init {
38
+ configParameters()
39
+ }
40
+
41
+ // 上报普通场景化API
42
+ fun reportFuncEvent (name : String , value : Map <String , Any >, ext : Map <String , Any >) {
43
+ Log .d(tag, " reportFuncEvent: $name value: $value ext: $ext " )
44
+ val eventMap = mapOf (ApiEventKey .TYPE to ApiEventType .API .value, ApiEventKey .DESC to name)
45
+ val labelMap = mapOf (ApiEventKey .API_VALUE to value, ApiEventKey .TIMESTAMP to getCurrentTs(), ApiEventKey .EXT to ext)
46
+ val event = convertToJSONString(eventMap) ? : " "
47
+ val label = convertToJSONString(labelMap) ? : " "
48
+ rtcEngine.sendCustomReportMessage(messageId, category, event, label, 0 )
49
+ }
50
+
51
+ fun startDurationEvent (name : String ) {
52
+ Log .d(tag, " startDurationEvent: $name " )
53
+ durationEventStartMap[name] = getCurrentTs()
54
+ }
55
+
56
+ fun endDurationEvent (name : String ) {
57
+ Log .d(tag, " endDurationEvent: $name " )
58
+ val beginTs = durationEventStartMap[name] ? : return
59
+ durationEventStartMap.remove(name)
60
+ val ts = getCurrentTs()
61
+ val cost = (ts - beginTs).toInt()
62
+
63
+ innerReportCostEvent(ts, name, cost)
64
+ }
65
+
66
+ // 上报耗时打点信息
67
+ fun reportCostEvent (name : String , cost : Int ) {
68
+ durationEventStartMap.remove(name)
69
+ innerReportCostEvent(
70
+ ts = getCurrentTs(),
71
+ name = name,
72
+ cost = cost
73
+ )
74
+ }
75
+
76
+ // 上报自定义信息
77
+ fun reportCustomEvent (name : String , ext : Map <String , Any >) {
78
+ Log .d(tag, " reportCustomEvent: $name ext: $ext " )
79
+ val eventMap = mapOf (ApiEventKey .TYPE to ApiEventType .CUSTOM .value, ApiEventKey .DESC to name)
80
+ val labelMap = mapOf (ApiEventKey .TIMESTAMP to getCurrentTs(), ApiEventKey .EXT to ext)
81
+ val event = convertToJSONString(eventMap) ? : " "
82
+ val label = convertToJSONString(labelMap) ? : " "
83
+ rtcEngine.sendCustomReportMessage(messageId, category, event, label, 0 )
84
+ }
85
+
86
+ fun writeLog (content : String , level : Int ) {
87
+ rtcEngine.writeLog(level, content)
88
+ }
89
+
90
+ fun cleanCache () {
91
+ durationEventStartMap.clear()
92
+ }
93
+
94
+ // ---------------------- private ----------------------
95
+
96
+ private fun configParameters () {
97
+ // rtcEngine.setParameters("{\"rtc.qos_for_test_purpose\": true}") //测试环境使用
98
+ // 数据上报
99
+ rtcEngine.setParameters(" {\" rtc.direct_send_custom_event\" : true}" )
100
+ // 日志写入
101
+ rtcEngine.setParameters(" {\" rtc.log_external_input\" : true}" )
102
+ }
103
+
104
+ private fun getCurrentTs (): Long {
105
+ return System .currentTimeMillis()
106
+ }
107
+
108
+ private fun innerReportCostEvent (ts : Long , name : String , cost : Int ) {
109
+ Log .d(tag, " reportCostEvent: $name cost: $cost ms" )
110
+ writeLog(" reportCostEvent: $name cost: $cost ms" , Constants .LOG_LEVEL_INFO )
111
+ val eventMap = mapOf (ApiEventKey .TYPE to ApiEventType .COST .value, ApiEventKey .DESC to name)
112
+ val labelMap = mapOf (ApiEventKey .TIMESTAMP to ts)
113
+ val event = convertToJSONString(eventMap) ? : " "
114
+ val label = convertToJSONString(labelMap) ? : " "
115
+ rtcEngine.sendCustomReportMessage(messageId, category, event, label, cost)
116
+ }
117
+
118
+ private fun convertToJSONString (dictionary : Map <String , Any >): String? {
119
+ return try {
120
+ JSONObject (dictionary).toString()
121
+ } catch (e: Exception ) {
122
+ writeLog(" [$tag ]convert to json fail: $e dictionary: $dictionary " , Constants .LOG_LEVEL_WARNING )
123
+ null
124
+ }
125
+ }
126
+ }
0 commit comments