Skip to content

Commit 361065f

Browse files
committed
[Android] Fxs The worker thread calls writeLog and sendCustomReportMessage.
1 parent 25877db commit 361065f

3 files changed

Lines changed: 189 additions & 138 deletions

File tree

Android/APIExample/app/src/main/java/io/agora/beautyapi/bytedance/utils/APIReporter.kt

Lines changed: 63 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,19 @@
11
package io.agora.beautyapi.bytedance.utils
22

3-
import android.util.Log
4-
import io.agora.rtc2.Constants
53
import io.agora.rtc2.RtcEngine
64
import org.json.JSONObject
5+
import java.util.concurrent.Executors
6+
import java.lang.ref.WeakReference
77

88
enum class APIType(val value: Int) {
9-
KTV(1), // K歌
10-
CALL(2), // 呼叫连麦
11-
BEAUTY(3), // 美颜
12-
VIDEO_LOADER(4), // 秒开秒切
13-
PK(5), // 团战
14-
VIRTUAL_SPACE(6), //
15-
SCREEN_SPACE(7), // 屏幕共享
16-
AUDIO_SCENARIO(8) // 音频
9+
KTV(1), // Karaoke
10+
CALL(2), // Call/Co-hosting
11+
BEAUTY(3), // Beauty
12+
VIDEO_LOADER(4), // Instant Loading
13+
PK(5), // Team Battle
14+
VIRTUAL_SPACE(6), // Virtual Space
15+
SCREEN_SPACE(7), // Screen Sharing
16+
AUDIO_SCENARIO(8) // Audio
1717
}
1818

1919
enum class ApiEventType(val value: Int) {
@@ -31,42 +31,49 @@ object ApiEventKey {
3131
}
3232

3333
object ApiCostEvent {
34-
const val CHANNEL_USAGE = "channelUsage" //频道使用耗时
35-
const val FIRST_FRAME_ACTUAL = "firstFrameActual" //首帧实际耗时
36-
const val FIRST_FRAME_PERCEIVED = "firstFramePerceived" //首帧感官耗时
34+
const val CHANNEL_USAGE = "channelUsage" // Channel usage duration
35+
const val FIRST_FRAME_ACTUAL = "firstFrameActual" // Actual first frame duration
36+
const val FIRST_FRAME_PERCEIVED = "firstFramePerceived" // Perceived first frame duration
3737
}
3838

3939
class APIReporter(
4040
private val type: APIType,
4141
private val version: String,
42-
private val rtcEngine: RtcEngine
42+
rtcEngine: RtcEngine
4343
) {
4444
private val tag = "APIReporter"
4545
private val messageId = "agora:scenarioAPI"
4646
private val durationEventStartMap = HashMap<String, Long>()
4747
private val category = "${type.value}_Android_$version"
48+
private val executorService = Executors.newSingleThreadExecutor()
49+
private val rtcEngineRef = WeakReference(rtcEngine)
4850

4951
init {
5052
configParameters()
5153
}
5254

53-
// 上报普通场景化API
55+
// Report regular scenario API
5456
fun reportFuncEvent(name: String, value: Map<String, Any>, ext: Map<String, Any>) {
55-
Log.d(tag, "reportFuncEvent: $name value: $value ext: $ext")
56-
val eventMap = mapOf(ApiEventKey.TYPE to ApiEventType.API.value, ApiEventKey.DESC to name)
57-
val labelMap = mapOf(ApiEventKey.API_VALUE to value, ApiEventKey.TIMESTAMP to getCurrentTs(), ApiEventKey.EXT to ext)
58-
val event = convertToJSONString(eventMap) ?: ""
59-
val label = convertToJSONString(labelMap) ?: ""
60-
rtcEngine.sendCustomReportMessage(messageId, category, event, label, 0)
57+
executorService.submit {
58+
rtcEngineRef.get()?.let {
59+
val eventMap = mapOf(ApiEventKey.TYPE to ApiEventType.API.value, ApiEventKey.DESC to name)
60+
val labelMap = mapOf(
61+
ApiEventKey.API_VALUE to value,
62+
ApiEventKey.TIMESTAMP to getCurrentTs(),
63+
ApiEventKey.EXT to ext
64+
)
65+
val event = convertToJSONString(eventMap) ?: ""
66+
val label = convertToJSONString(labelMap) ?: ""
67+
it.sendCustomReportMessage(messageId, category, event, label, 0)
68+
}
69+
}
6170
}
6271

6372
fun startDurationEvent(name: String) {
64-
Log.d(tag, "startDurationEvent: $name")
6573
durationEventStartMap[name] = getCurrentTs()
6674
}
6775

6876
fun endDurationEvent(name: String, ext: Map<String, Any>) {
69-
Log.d(tag, "endDurationEvent: $name")
7077
val beginTs = durationEventStartMap[name] ?: return
7178
durationEventStartMap.remove(name)
7279
val ts = getCurrentTs()
@@ -75,7 +82,7 @@ class APIReporter(
7582
innerReportCostEvent(ts, name, cost, ext)
7683
}
7784

78-
// 上报耗时打点信息
85+
// Report time-consuming event point information
7986
fun reportCostEvent(name: String, cost: Int, ext: Map<String, Any>) {
8087
durationEventStartMap.remove(name)
8188
innerReportCostEvent(
@@ -86,18 +93,21 @@ class APIReporter(
8693
)
8794
}
8895

89-
// 上报自定义信息
96+
// Report custom information
9097
fun reportCustomEvent(name: String, ext: Map<String, Any>) {
91-
Log.d(tag, "reportCustomEvent: $name ext: $ext")
92-
val eventMap = mapOf(ApiEventKey.TYPE to ApiEventType.CUSTOM.value, ApiEventKey.DESC to name)
93-
val labelMap = mapOf(ApiEventKey.TIMESTAMP to getCurrentTs(), ApiEventKey.EXT to ext)
94-
val event = convertToJSONString(eventMap) ?: ""
95-
val label = convertToJSONString(labelMap) ?: ""
96-
rtcEngine.sendCustomReportMessage(messageId, category, event, label, 0)
98+
executorService.submit {
99+
rtcEngineRef.get()?.let {
100+
val eventMap = mapOf(ApiEventKey.TYPE to ApiEventType.CUSTOM.value, ApiEventKey.DESC to name)
101+
val labelMap = mapOf(ApiEventKey.TIMESTAMP to getCurrentTs(), ApiEventKey.EXT to ext)
102+
val event = convertToJSONString(eventMap) ?: ""
103+
val label = convertToJSONString(labelMap) ?: ""
104+
it.sendCustomReportMessage(messageId, category, event, label, 0)
105+
}
106+
}
97107
}
98108

99-
fun writeLog(content: String, level: Int) {
100-
rtcEngine.writeLog(level, content)
109+
private fun writeLog(content: String, level: Int) {
110+
rtcEngineRef.get()?.writeLog(level, content)
101111
}
102112

103113
fun cleanCache() {
@@ -107,32 +117,39 @@ class APIReporter(
107117
// ---------------------- private ----------------------
108118

109119
private fun configParameters() {
110-
//rtcEngine.setParameters("{\"rtc.qos_for_test_purpose\": true}") //测试环境使用
111-
// 数据上报
112-
rtcEngine.setParameters("{\"rtc.direct_send_custom_event\": true}")
113-
// 日志写入
114-
rtcEngine.setParameters("{\"rtc.log_external_input\": true}")
120+
executorService.submit {
121+
rtcEngineRef.get()?.let {
122+
// it.setParameters("{\"rtc.qos_for_test_purpose\": true}") // Used for test environment
123+
// Data reporting
124+
it.setParameters("{\"rtc.direct_send_custom_event\": true}")
125+
// Log writing
126+
it.setParameters("{\"rtc.log_external_input\": true}")
127+
}
128+
}
115129
}
116130

117131
private fun getCurrentTs(): Long {
118132
return System.currentTimeMillis()
119133
}
120134

121135
private fun innerReportCostEvent(ts: Long, name: String, cost: Int, ext: Map<String, Any>) {
122-
Log.d(tag, "reportCostEvent: $name cost: $cost ms ext: $ext")
123-
writeLog("reportCostEvent: $name cost: $cost ms", Constants.LOG_LEVEL_INFO)
124-
val eventMap = mapOf(ApiEventKey.TYPE to ApiEventType.COST.value, ApiEventKey.DESC to name)
125-
val labelMap = mapOf(ApiEventKey.TIMESTAMP to ts, ApiEventKey.EXT to ext)
126-
val event = convertToJSONString(eventMap) ?: ""
127-
val label = convertToJSONString(labelMap) ?: ""
128-
rtcEngine.sendCustomReportMessage(messageId, category, event, label, cost)
136+
executorService.submit {
137+
rtcEngineRef.get()?.let {
138+
// writeLog("reportCostEvent: $name cost: $cost ms", Constants.LOG_LEVEL_INFO)
139+
val eventMap = mapOf(ApiEventKey.TYPE to ApiEventType.COST.value, ApiEventKey.DESC to name)
140+
val labelMap = mapOf(ApiEventKey.TIMESTAMP to ts, ApiEventKey.EXT to ext)
141+
val event = convertToJSONString(eventMap) ?: ""
142+
val label = convertToJSONString(labelMap) ?: ""
143+
it.sendCustomReportMessage(messageId, category, event, label, cost)
144+
}
145+
}
129146
}
130147

131148
private fun convertToJSONString(dictionary: Map<String, Any>): String? {
132149
return try {
133150
JSONObject(dictionary).toString()
134151
} catch (e: Exception) {
135-
writeLog("[$tag]convert to json fail: $e dictionary: $dictionary", Constants.LOG_LEVEL_WARNING)
152+
LogUtils.e(tag, "convert to json fail: $e dictionary: $dictionary")
136153
null
137154
}
138155
}

Android/APIExample/app/src/main/java/io/agora/beautyapi/faceunity/utils/APIReporter.kt

Lines changed: 63 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,19 @@
11
package io.agora.beautyapi.faceunity.utils
22

3-
import android.util.Log
4-
import io.agora.rtc2.Constants
53
import io.agora.rtc2.RtcEngine
64
import org.json.JSONObject
5+
import java.util.concurrent.Executors
6+
import java.lang.ref.WeakReference
77

88
enum class APIType(val value: Int) {
9-
KTV(1), // K歌
10-
CALL(2), // 呼叫连麦
11-
BEAUTY(3), // 美颜
12-
VIDEO_LOADER(4), // 秒开秒切
13-
PK(5), // 团战
14-
VIRTUAL_SPACE(6), //
15-
SCREEN_SPACE(7), // 屏幕共享
16-
AUDIO_SCENARIO(8) // 音频
9+
KTV(1), // Karaoke
10+
CALL(2), // Call/Co-hosting
11+
BEAUTY(3), // Beauty
12+
VIDEO_LOADER(4), // Instant Loading
13+
PK(5), // Team Battle
14+
VIRTUAL_SPACE(6), // Virtual Space
15+
SCREEN_SPACE(7), // Screen Sharing
16+
AUDIO_SCENARIO(8) // Audio
1717
}
1818

1919
enum class ApiEventType(val value: Int) {
@@ -31,42 +31,49 @@ object ApiEventKey {
3131
}
3232

3333
object ApiCostEvent {
34-
const val CHANNEL_USAGE = "channelUsage" //频道使用耗时
35-
const val FIRST_FRAME_ACTUAL = "firstFrameActual" //首帧实际耗时
36-
const val FIRST_FRAME_PERCEIVED = "firstFramePerceived" //首帧感官耗时
34+
const val CHANNEL_USAGE = "channelUsage" // Channel usage duration
35+
const val FIRST_FRAME_ACTUAL = "firstFrameActual" // Actual first frame duration
36+
const val FIRST_FRAME_PERCEIVED = "firstFramePerceived" // Perceived first frame duration
3737
}
3838

3939
class APIReporter(
4040
private val type: APIType,
4141
private val version: String,
42-
private val rtcEngine: RtcEngine
42+
rtcEngine: RtcEngine
4343
) {
4444
private val tag = "APIReporter"
4545
private val messageId = "agora:scenarioAPI"
4646
private val durationEventStartMap = HashMap<String, Long>()
4747
private val category = "${type.value}_Android_$version"
48+
private val executorService = Executors.newSingleThreadExecutor()
49+
private val rtcEngineRef = WeakReference(rtcEngine)
4850

4951
init {
5052
configParameters()
5153
}
5254

53-
// 上报普通场景化API
55+
// Report regular scenario API
5456
fun reportFuncEvent(name: String, value: Map<String, Any>, ext: Map<String, Any>) {
55-
Log.d(tag, "reportFuncEvent: $name value: $value ext: $ext")
56-
val eventMap = mapOf(ApiEventKey.TYPE to ApiEventType.API.value, ApiEventKey.DESC to name)
57-
val labelMap = mapOf(ApiEventKey.API_VALUE to value, ApiEventKey.TIMESTAMP to getCurrentTs(), ApiEventKey.EXT to ext)
58-
val event = convertToJSONString(eventMap) ?: ""
59-
val label = convertToJSONString(labelMap) ?: ""
60-
rtcEngine.sendCustomReportMessage(messageId, category, event, label, 0)
57+
executorService.submit {
58+
rtcEngineRef.get()?.let {
59+
val eventMap = mapOf(ApiEventKey.TYPE to ApiEventType.API.value, ApiEventKey.DESC to name)
60+
val labelMap = mapOf(
61+
ApiEventKey.API_VALUE to value,
62+
ApiEventKey.TIMESTAMP to getCurrentTs(),
63+
ApiEventKey.EXT to ext
64+
)
65+
val event = convertToJSONString(eventMap) ?: ""
66+
val label = convertToJSONString(labelMap) ?: ""
67+
it.sendCustomReportMessage(messageId, category, event, label, 0)
68+
}
69+
}
6170
}
6271

6372
fun startDurationEvent(name: String) {
64-
Log.d(tag, "startDurationEvent: $name")
6573
durationEventStartMap[name] = getCurrentTs()
6674
}
6775

6876
fun endDurationEvent(name: String, ext: Map<String, Any>) {
69-
Log.d(tag, "endDurationEvent: $name")
7077
val beginTs = durationEventStartMap[name] ?: return
7178
durationEventStartMap.remove(name)
7279
val ts = getCurrentTs()
@@ -75,7 +82,7 @@ class APIReporter(
7582
innerReportCostEvent(ts, name, cost, ext)
7683
}
7784

78-
// 上报耗时打点信息
85+
// Report time-consuming event point information
7986
fun reportCostEvent(name: String, cost: Int, ext: Map<String, Any>) {
8087
durationEventStartMap.remove(name)
8188
innerReportCostEvent(
@@ -86,18 +93,21 @@ class APIReporter(
8693
)
8794
}
8895

89-
// 上报自定义信息
96+
// Report custom information
9097
fun reportCustomEvent(name: String, ext: Map<String, Any>) {
91-
Log.d(tag, "reportCustomEvent: $name ext: $ext")
92-
val eventMap = mapOf(ApiEventKey.TYPE to ApiEventType.CUSTOM.value, ApiEventKey.DESC to name)
93-
val labelMap = mapOf(ApiEventKey.TIMESTAMP to getCurrentTs(), ApiEventKey.EXT to ext)
94-
val event = convertToJSONString(eventMap) ?: ""
95-
val label = convertToJSONString(labelMap) ?: ""
96-
rtcEngine.sendCustomReportMessage(messageId, category, event, label, 0)
98+
executorService.submit {
99+
rtcEngineRef.get()?.let {
100+
val eventMap = mapOf(ApiEventKey.TYPE to ApiEventType.CUSTOM.value, ApiEventKey.DESC to name)
101+
val labelMap = mapOf(ApiEventKey.TIMESTAMP to getCurrentTs(), ApiEventKey.EXT to ext)
102+
val event = convertToJSONString(eventMap) ?: ""
103+
val label = convertToJSONString(labelMap) ?: ""
104+
it.sendCustomReportMessage(messageId, category, event, label, 0)
105+
}
106+
}
97107
}
98108

99-
fun writeLog(content: String, level: Int) {
100-
rtcEngine.writeLog(level, content)
109+
private fun writeLog(content: String, level: Int) {
110+
rtcEngineRef.get()?.writeLog(level, content)
101111
}
102112

103113
fun cleanCache() {
@@ -107,32 +117,39 @@ class APIReporter(
107117
// ---------------------- private ----------------------
108118

109119
private fun configParameters() {
110-
//rtcEngine.setParameters("{\"rtc.qos_for_test_purpose\": true}") //测试环境使用
111-
// 数据上报
112-
rtcEngine.setParameters("{\"rtc.direct_send_custom_event\": true}")
113-
// 日志写入
114-
rtcEngine.setParameters("{\"rtc.log_external_input\": true}")
120+
executorService.submit {
121+
rtcEngineRef.get()?.let {
122+
// it.setParameters("{\"rtc.qos_for_test_purpose\": true}") // Used for test environment
123+
// Data reporting
124+
it.setParameters("{\"rtc.direct_send_custom_event\": true}")
125+
// Log writing
126+
it.setParameters("{\"rtc.log_external_input\": true}")
127+
}
128+
}
115129
}
116130

117131
private fun getCurrentTs(): Long {
118132
return System.currentTimeMillis()
119133
}
120134

121135
private fun innerReportCostEvent(ts: Long, name: String, cost: Int, ext: Map<String, Any>) {
122-
Log.d(tag, "reportCostEvent: $name cost: $cost ms ext: $ext")
123-
writeLog("reportCostEvent: $name cost: $cost ms", Constants.LOG_LEVEL_INFO)
124-
val eventMap = mapOf(ApiEventKey.TYPE to ApiEventType.COST.value, ApiEventKey.DESC to name)
125-
val labelMap = mapOf(ApiEventKey.TIMESTAMP to ts, ApiEventKey.EXT to ext)
126-
val event = convertToJSONString(eventMap) ?: ""
127-
val label = convertToJSONString(labelMap) ?: ""
128-
rtcEngine.sendCustomReportMessage(messageId, category, event, label, cost)
136+
executorService.submit {
137+
rtcEngineRef.get()?.let {
138+
// writeLog("reportCostEvent: $name cost: $cost ms", Constants.LOG_LEVEL_INFO)
139+
val eventMap = mapOf(ApiEventKey.TYPE to ApiEventType.COST.value, ApiEventKey.DESC to name)
140+
val labelMap = mapOf(ApiEventKey.TIMESTAMP to ts, ApiEventKey.EXT to ext)
141+
val event = convertToJSONString(eventMap) ?: ""
142+
val label = convertToJSONString(labelMap) ?: ""
143+
it.sendCustomReportMessage(messageId, category, event, label, cost)
144+
}
145+
}
129146
}
130147

131148
private fun convertToJSONString(dictionary: Map<String, Any>): String? {
132149
return try {
133150
JSONObject(dictionary).toString()
134151
} catch (e: Exception) {
135-
writeLog("[$tag]convert to json fail: $e dictionary: $dictionary", Constants.LOG_LEVEL_WARNING)
152+
LogUtils.e(tag, "convert to json fail: $e dictionary: $dictionary")
136153
null
137154
}
138155
}

0 commit comments

Comments
 (0)