merge
This commit is contained in:
@@ -54,7 +54,7 @@ android {
|
||||
}
|
||||
protobuf {
|
||||
protoc {
|
||||
artifact = rootProject.ext.dependencies.google_protoc
|
||||
artifact = rootProject.ext.dependencies.protoc
|
||||
}
|
||||
generateProtoTasks {
|
||||
all().each { task ->
|
||||
@@ -76,10 +76,9 @@ dependencies {
|
||||
|
||||
implementation rootProject.ext.dependencies.androidx_datastore
|
||||
implementation rootProject.ext.dependencies.androidxroomruntime
|
||||
implementation rootProject.ext.dependencies.androidxroomktx
|
||||
kapt rootProject.ext.dependencies.androidxroomcompiler
|
||||
|
||||
implementation rootProject.ext.dependencies.google_proto_java
|
||||
implementation rootProject.ext.dependencies.androidxroomktx
|
||||
implementation rootProject.ext.dependencies.protobuf_java
|
||||
implementation rootProject.ext.dependencies.androidxappcompat
|
||||
implementation rootProject.ext.dependencies.androidxconstraintlayout
|
||||
implementation rootProject.ext.dependencies.androidxrecyclerview
|
||||
|
||||
@@ -4,13 +4,13 @@ import android.annotation.SuppressLint
|
||||
import android.content.Context
|
||||
import android.view.View
|
||||
import com.alibaba.android.arouter.facade.annotation.Route
|
||||
import com.mogo.eagle.core.data.deva.chain.ChainLogParam
|
||||
import com.mogo.eagle.core.data.autopilot.AutoPilotRecordResult
|
||||
import com.mogo.eagle.core.data.chain.ChainLogParam
|
||||
import com.mogo.eagle.core.data.constants.MogoServicePaths
|
||||
import com.mogo.eagle.core.function.api.devatools.IDevaToolsProvider
|
||||
import com.zhjt.mogo_core_function_devatools.badcase.BadCaseManager
|
||||
import com.zhjt.mogo_core_function_devatools.logcatch.MogoLogCatchManager
|
||||
import com.zhjt.mogo_core_function_devatools.trace.TraceManager.Companion.traceManager
|
||||
import record_cache.RecordPanelOuterClass
|
||||
|
||||
@Route(path = MogoServicePaths.PATH_DEVA_TOOLS)
|
||||
class DevaToolsProvider : IDevaToolsProvider {
|
||||
@@ -52,7 +52,7 @@ class DevaToolsProvider : IDevaToolsProvider {
|
||||
BadCaseManager.init(view, onShow, onHide)
|
||||
}
|
||||
|
||||
override fun onReceiveBadCaseRecord(record: AutoPilotRecordResult) {
|
||||
override fun onReceiveBadCaseRecord(record: RecordPanelOuterClass.RecordPanel) {
|
||||
BadCaseManager.onReceiveBadCaseRecord(record)
|
||||
}
|
||||
|
||||
|
||||
@@ -2,7 +2,6 @@ package com.zhjt.mogo_core_function_devatools.badcase
|
||||
|
||||
import android.transition.AutoTransition
|
||||
import android.transition.TransitionManager
|
||||
import android.util.Log
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import androidx.lifecycle.Lifecycle.Event
|
||||
@@ -12,18 +11,20 @@ import androidx.lifecycle.LifecycleEventObserver
|
||||
import androidx.lifecycle.LifecycleOwner
|
||||
import androidx.lifecycle.lifecycleScope
|
||||
import com.mogo.cloud.passport.MoGoAiCloudClientConfig
|
||||
import com.mogo.eagle.core.data.autopilot.AutoPilotRecordResult
|
||||
import com.mogo.eagle.core.utilcode.mogo.logger.scene.SceneConstant.Companion.M_DEVA
|
||||
import com.mogo.eagle.core.function.call.hmi.CallerHmiManager
|
||||
import com.mogo.eagle.core.utilcode.mogo.logger.CallerLogger
|
||||
import com.mogo.eagle.core.utilcode.kotlin.lifecycleOwner
|
||||
import com.mogo.eagle.core.utilcode.kotlin.onClick
|
||||
import com.mogo.eagle.core.utilcode.util.ToastUtils
|
||||
import com.mogo.eagle.core.utilcode.util.Utils
|
||||
import com.zhjt.mogo_core_function_devatools.badcase.repository.net.api.entity.BadCaseResponse.Reason
|
||||
import com.zhjt.mogo_core_function_devatools.badcase.biz.BadCasePresenter
|
||||
import com.zhjt.mogo_core_function_devatools.badcase.biz.BadCaseView
|
||||
import com.zhjt.mogo_core_function_devatools.badcase.api.entity.BadCaseResponse.Reason
|
||||
import com.zhjt.mogo_core_function_devatools.badcase.mvp.BadCasePresenter
|
||||
import com.zhjt.mogo_core_function_devatools.badcase.mvp.BadCaseView
|
||||
import com.zhjt.mogo_core_function_devatools.badcase.repository.db.entity.AutoPilotRecord
|
||||
import kotlinx.coroutines.*
|
||||
import kotlinx.coroutines.channels.Channel
|
||||
import record_cache.RecordPanelOuterClass
|
||||
import java.lang.ref.WeakReference
|
||||
import java.util.concurrent.TimeUnit
|
||||
|
||||
@@ -35,9 +36,10 @@ internal object BadCaseManager : LifecycleEventObserver {
|
||||
* 超过此时间,case入口自动消失
|
||||
*/
|
||||
|
||||
private val CASE_EXPIRE_DURATION: Long = TimeUnit.HOURS.toMillis(4)/* TimeUnit.SECONDS.toMillis(10) */
|
||||
private val CASE_EXPIRE_DURATION: Long =
|
||||
TimeUnit.HOURS.toMillis(4)/* TimeUnit.SECONDS.toMillis(10) */
|
||||
|
||||
private var onShow: (() -> Unit)? = null
|
||||
private var onShow: (() -> Unit)? = null
|
||||
private var onHide: (() -> Unit)? = null
|
||||
|
||||
private var hideFloat: (() -> Unit)? = null
|
||||
@@ -46,7 +48,7 @@ internal object BadCaseManager : LifecycleEventObserver {
|
||||
private var record: AutoPilotRecord? = null
|
||||
|
||||
@Volatile
|
||||
private var viewHolder : WeakReference<View>? = null
|
||||
private var viewHolder: WeakReference<View>? = null
|
||||
|
||||
@Volatile
|
||||
private var dismissJob: Job? = null
|
||||
@@ -86,22 +88,22 @@ internal object BadCaseManager : LifecycleEventObserver {
|
||||
private fun register() {
|
||||
scope?.launch(Dispatchers.Default) {
|
||||
while (true) {
|
||||
Log.d(TAG, "---- 开始监听BadCase事件 ----")
|
||||
CallerLogger.d("$M_DEVA$TAG", "---- 开始监听BadCase事件 ----")
|
||||
val old = record
|
||||
if (old == null || old.consumed) {
|
||||
Log.d(TAG, "---- 当前事件已消费 -- value: $old")
|
||||
CallerLogger.d("$M_DEVA$TAG", "---- 当前事件已消费 -- value: $old")
|
||||
var receive = channel.receive()
|
||||
var oldT = record?.toLongTime() ?: 0L
|
||||
var newT = receive.toLongTime()
|
||||
if (isValid(oldT, newT)) {
|
||||
record = receive
|
||||
Log.d(TAG, "---- 时间有效,开始展示入口 ---")
|
||||
CallerLogger.d("$M_DEVA$TAG", "---- 时间有效,开始展示入口 ---")
|
||||
withContext(Dispatchers.Main) {
|
||||
showBadCaseInternal(receive)
|
||||
}
|
||||
continue
|
||||
}
|
||||
Log.d(TAG, "---- 时间无效,移除管道中无用数据 ---")
|
||||
CallerLogger.d("$M_DEVA$TAG", "---- 时间无效,移除管道中无用数据 ---")
|
||||
presenter.deleteRecord(receive)
|
||||
while (oldT != 0L && newT != 0L && (newT - oldT) >= CASE_EXPIRE_DURATION) {
|
||||
oldT = newT
|
||||
@@ -110,14 +112,17 @@ internal object BadCaseManager : LifecycleEventObserver {
|
||||
presenter.deleteRecord(receive)
|
||||
}
|
||||
receive.takeIf { it.key != old?.key }?.also {
|
||||
Log.d(TAG, "record: [$record] is displaying for rest ...")
|
||||
CallerLogger.d(
|
||||
"$M_DEVA$TAG",
|
||||
"record: [$record] is displaying for rest ..."
|
||||
)
|
||||
record = receive
|
||||
withContext(Dispatchers.Main) {
|
||||
showBadCaseInternal(it)
|
||||
}
|
||||
}
|
||||
} else {
|
||||
Log.d(TAG, "record: [$old] hasn't been consumed~~~~")
|
||||
CallerLogger.d("$M_DEVA$TAG", "record: [$old] hasn't been consumed~~~~")
|
||||
withContext(Dispatchers.Main) {
|
||||
showEntry()
|
||||
}
|
||||
@@ -133,26 +138,26 @@ internal object BadCaseManager : LifecycleEventObserver {
|
||||
val lastModified = presenter.getLastModified()
|
||||
val list = withContext(Dispatchers.IO) {
|
||||
try {
|
||||
Log.d(TAG, " --- 1 ----")
|
||||
Log.d(TAG, "恢复持久化的数据 - 最后修改时间:$lastModified")
|
||||
presenter.getUnConsumedRecords().fold(mutableListOf<AutoPilotRecord>()) {
|
||||
acc, record ->
|
||||
if (isValid(lastModified, record.toLongTime())) {
|
||||
acc.add(record)
|
||||
} else {
|
||||
presenter.deleteRecord(record)
|
||||
CallerLogger.d("$M_DEVA$TAG", " --- 1 ----")
|
||||
CallerLogger.d("$M_DEVA$TAG", "恢复持久化的数据 - 最后修改时间:$lastModified")
|
||||
presenter.getUnConsumedRecords()
|
||||
.fold(mutableListOf<AutoPilotRecord>()) { acc, record ->
|
||||
if (isValid(lastModified, record.toLongTime())) {
|
||||
acc.add(record)
|
||||
} else {
|
||||
presenter.deleteRecord(record)
|
||||
}
|
||||
acc
|
||||
}
|
||||
acc
|
||||
}
|
||||
} catch (t: Throwable) {
|
||||
emptyList()
|
||||
}
|
||||
}
|
||||
if (list.isEmpty()) {
|
||||
Log.d(TAG, "没有要恢复的数据")
|
||||
CallerLogger.d("$M_DEVA$TAG", "没有要恢复的数据")
|
||||
} else {
|
||||
list.forEach {
|
||||
Log.d(TAG, "恢复的接管数据:$it")
|
||||
CallerLogger.d("$M_DEVA$TAG", "恢复的接管数据:$it")
|
||||
channel.send(it)
|
||||
}
|
||||
}
|
||||
@@ -164,7 +169,7 @@ internal object BadCaseManager : LifecycleEventObserver {
|
||||
return oldT == 0L || newT == 0L || (newT - oldT >= 0 && (newT - oldT) < CASE_EXPIRE_DURATION)
|
||||
}
|
||||
|
||||
fun onReceiveBadCaseRecord(record: AutoPilotRecordResult) {
|
||||
fun onReceiveBadCaseRecord(record: RecordPanelOuterClass.RecordPanel) {
|
||||
scope?.launch {
|
||||
val newRecord = record.toRecord()
|
||||
withContext(Dispatchers.IO) {
|
||||
@@ -185,15 +190,16 @@ internal object BadCaseManager : LifecycleEventObserver {
|
||||
hideFloat = null
|
||||
},
|
||||
onSelect = { reason ->
|
||||
val uploadResult = presenter.upload(mutableMapOf<String, String>().also { itx ->
|
||||
itx["carLicense"] = MoGoAiCloudClientConfig.getInstance().sn
|
||||
itx["filename"] = record.fileName ?: ""
|
||||
itx["filesize"] = record.total.toString()
|
||||
itx["key"] = record.key ?: ""
|
||||
itx["reason"] = reason.reason ?: ""
|
||||
itx["duration"] = record.duration.toInt().toString()
|
||||
itx["timestamp"] = record.timestamp
|
||||
})
|
||||
val uploadResult =
|
||||
presenter.upload(mutableMapOf<String, String>().also { itx ->
|
||||
itx["carLicense"] = MoGoAiCloudClientConfig.getInstance().sn
|
||||
itx["filename"] = record.fileName ?: ""
|
||||
itx["filesize"] = record.total.toString()
|
||||
itx["key"] = record.key ?: ""
|
||||
itx["reason"] = reason.reason ?: ""
|
||||
itx["duration"] = record.duration.toInt().toString()
|
||||
itx["timestamp"] = record.timestamp
|
||||
})
|
||||
if (uploadResult == null || uploadResult.code != 200) {
|
||||
ToastUtils.showShort("接管反馈失败")
|
||||
} else {
|
||||
@@ -240,7 +246,10 @@ internal object BadCaseManager : LifecycleEventObserver {
|
||||
}
|
||||
}
|
||||
|
||||
private fun showBadCaseFloat(onDismiss: () -> Unit, onSelect:suspend (reason: Reason) -> Unit) {
|
||||
private fun showBadCaseFloat(
|
||||
onDismiss: () -> Unit,
|
||||
onSelect: suspend (reason: Reason) -> Unit
|
||||
) {
|
||||
val context = viewHolder?.get()?.context ?: Utils.getApp()
|
||||
BadCaseView(context).also {
|
||||
it.register(record, onDismiss, onSelect)
|
||||
@@ -258,7 +267,7 @@ internal object BadCaseManager : LifecycleEventObserver {
|
||||
}
|
||||
}
|
||||
|
||||
fun <T: View> T.toggle(show: Boolean) {
|
||||
fun <T : View> T.toggle(show: Boolean) {
|
||||
val group = (parent as? ViewGroup) ?: return
|
||||
val target = if (show) View.VISIBLE else View.GONE
|
||||
takeIf { it.visibility != target }?.also {
|
||||
@@ -267,15 +276,16 @@ fun <T: View> T.toggle(show: Boolean) {
|
||||
}
|
||||
}
|
||||
|
||||
internal fun AutoPilotRecordResult.toRecord(): AutoPilotRecord = AutoPilotRecord().also {
|
||||
it.id = this.id
|
||||
it.stat = this.stat
|
||||
it.key = this.key
|
||||
it.note = this.note
|
||||
it.type = this.type
|
||||
it.total = this.total
|
||||
it.fileName = this.fileName
|
||||
it.duration = this.duration
|
||||
it.diskFree = this.diskFree
|
||||
it.consumed = false
|
||||
}
|
||||
internal fun RecordPanelOuterClass.RecordPanel.toRecord(): AutoPilotRecord =
|
||||
AutoPilotRecord().also {
|
||||
it.id = this.id
|
||||
it.stat = this.stat
|
||||
it.key = this.key.toString()
|
||||
it.note = this.note
|
||||
it.type = this.type
|
||||
it.total = this.totalSize
|
||||
it.fileName = this.filename
|
||||
it.duration = this.duration.toDouble()
|
||||
it.diskFree = this.diskFree
|
||||
it.consumed = false
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
package com.zhjt.mogo_core_function_devatools.badcase.api
|
||||
|
||||
import com.zhjt.mogo_core_function_devatools.badcase.api.entity.BadCaseResponse
|
||||
import com.zhjt.mogo_core_function_devatools.badcase.api.entity.UploadResult
|
||||
import retrofit2.Response
|
||||
import retrofit2.http.FieldMap
|
||||
import retrofit2.http.FormUrlEncoded
|
||||
import retrofit2.http.GET
|
||||
import retrofit2.http.POST
|
||||
|
||||
internal interface BadCaseApi {
|
||||
|
||||
@FormUrlEncoded
|
||||
@POST("/yycp-vehicle-management-service/tool/badcase/add")
|
||||
suspend fun post(@FieldMap map: Map<String, String>): Response<UploadResult>
|
||||
|
||||
@GET("/yycp-vehicle-management-service/tool/badcase/reasons")
|
||||
suspend fun get(): Response<BadCaseResponse>
|
||||
}
|
||||
@@ -0,0 +1,28 @@
|
||||
package com.zhjt.mogo_core_function_devatools.badcase.api.entity
|
||||
|
||||
import androidx.annotation.Keep
|
||||
import com.google.gson.annotations.Expose
|
||||
|
||||
@Keep
|
||||
internal class BadCaseResponse {
|
||||
var code: Int = -1
|
||||
var data: List<Reason>? = null
|
||||
var msg: String? = null
|
||||
var success: Boolean = false
|
||||
var total: Int = -1
|
||||
|
||||
@Expose(serialize = false, deserialize = false)
|
||||
var isBuildIn: Boolean = false
|
||||
|
||||
@Keep
|
||||
class Reason {
|
||||
var id: String? = null
|
||||
var reason: String? = null
|
||||
|
||||
/**
|
||||
* 业务字段,不参与序列化和反序列化
|
||||
*/
|
||||
@Expose(deserialize = false, serialize = false)
|
||||
var isChecked: Boolean = false
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,15 @@
|
||||
package com.zhjt.mogo_core_function_devatools.badcase.api.entity
|
||||
|
||||
import androidx.annotation.Keep
|
||||
|
||||
@Keep
|
||||
internal class UploadResult {
|
||||
var code: Int = -1
|
||||
var msg: String? = null
|
||||
var data: Array<String>? = null
|
||||
var success: Boolean = false
|
||||
|
||||
override fun toString(): String {
|
||||
return "UploadResult(code=$code, msg=$msg, data=${data?.contentToString()}, success=$success)"
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,54 @@
|
||||
package com.zhjt.mogo_core_function_devatools.badcase.mvp
|
||||
|
||||
import com.mogo.eagle.core.utilcode.mogo.logger.scene.SceneConstant.Companion.M_DEVA
|
||||
import com.mogo.eagle.core.utilcode.mogo.logger.CallerLogger
|
||||
import com.zhjt.mogo_core_function_devatools.badcase.BadCaseManager
|
||||
import com.zhjt.mogo_core_function_devatools.badcase.api.entity.UploadResult
|
||||
import com.zhjt.mogo_core_function_devatools.badcase.mvp.biz.IBadCasePresenter
|
||||
import com.zhjt.mogo_core_function_devatools.badcase.repository.Repository
|
||||
import com.zhjt.mogo_core_function_devatools.badcase.repository.db.entity.AutoPilotRecord
|
||||
|
||||
internal class BadCasePresenter : IBadCasePresenter {
|
||||
|
||||
private val repository by lazy {
|
||||
Repository()
|
||||
}
|
||||
|
||||
override suspend fun loadBadCases() = repository.loadBadCases()
|
||||
|
||||
override suspend fun insertRecord(record: AutoPilotRecord) {
|
||||
try {
|
||||
repository.insert(record)
|
||||
} catch (t: Throwable) {
|
||||
CallerLogger.e("$M_DEVA${BadCaseManager.TAG}", "-- 插入数据失败 -- msg: $t")
|
||||
}
|
||||
}
|
||||
|
||||
override suspend fun getUnConsumedRecords(): List<AutoPilotRecord> {
|
||||
return try {
|
||||
repository.getAllUnConsumedRecord() ?: emptyList()
|
||||
} catch (t: Throwable) {
|
||||
CallerLogger.e("$M_DEVA${BadCaseManager.TAG}", "-- 获取所有未消费的数据失败 -- msg: $t")
|
||||
emptyList()
|
||||
}
|
||||
}
|
||||
|
||||
override suspend fun deleteRecord(record: AutoPilotRecord) {
|
||||
try {
|
||||
repository.deleteRecord(record)
|
||||
} catch (t: Throwable) {
|
||||
CallerLogger.e("$M_DEVA${BadCaseManager.TAG}", "-- 删除某条记录失败 -- msg: $t")
|
||||
}
|
||||
}
|
||||
|
||||
override suspend fun upload(map: Map<String, String>): UploadResult? = repository.upload(map)
|
||||
|
||||
override suspend fun updateLastModified(timestamp: Long) {
|
||||
repository.uploadLastModified(timestamp)
|
||||
}
|
||||
|
||||
override suspend fun getLastModified(): Long {
|
||||
CallerLogger.d("$M_DEVA${BadCaseManager.TAG}", " --- 2 ----")
|
||||
return repository.getLastModified()
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,176 @@
|
||||
package com.zhjt.mogo_core_function_devatools.badcase.mvp
|
||||
|
||||
import android.annotation.SuppressLint
|
||||
import android.content.Context
|
||||
import android.graphics.Color
|
||||
import android.graphics.drawable.ColorDrawable
|
||||
import android.graphics.drawable.GradientDrawable
|
||||
import android.graphics.drawable.StateListDrawable
|
||||
import android.util.AttributeSet
|
||||
import android.util.StateSet
|
||||
import android.view.LayoutInflater
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import android.widget.ImageView
|
||||
import android.widget.TextView
|
||||
import androidx.constraintlayout.widget.ConstraintLayout
|
||||
import androidx.core.content.ContextCompat
|
||||
import androidx.lifecycle.lifecycleScope
|
||||
import androidx.recyclerview.widget.LinearLayoutManager
|
||||
import androidx.recyclerview.widget.RecyclerView
|
||||
import com.mogo.eagle.core.data.autopilot.AutoPilotRecordResult
|
||||
import com.mogo.eagle.core.utilcode.kotlin.*
|
||||
import com.zhjt.mogo_core_function_devatools.R
|
||||
import com.zhjt.mogo_core_function_devatools.badcase.api.entity.BadCaseResponse.Reason
|
||||
import com.zhjt.mogo_core_function_devatools.badcase.repository.db.entity.AutoPilotRecord
|
||||
import kotlinx.android.synthetic.main.layout_badcase_collect.view.*
|
||||
import kotlinx.coroutines.launch
|
||||
import java.text.SimpleDateFormat
|
||||
import java.util.*
|
||||
|
||||
internal class BadCaseView: ConstraintLayout {
|
||||
|
||||
@Volatile
|
||||
private var selectCase: Reason? = null
|
||||
|
||||
@Volatile
|
||||
private var cases: List<Reason>? = null
|
||||
|
||||
private val presenter by lazy {
|
||||
BadCasePresenter()
|
||||
}
|
||||
|
||||
private var onDismiss: (() -> Unit)? = null
|
||||
private var onSelect:(suspend (reason: Reason) -> Unit)? = null
|
||||
|
||||
private val scope by lazy {
|
||||
lifecycleOwner.lifecycleScope
|
||||
}
|
||||
|
||||
private var record: AutoPilotRecord? = null
|
||||
|
||||
constructor(context: Context) : this(context, null)
|
||||
|
||||
constructor(context: Context, attrs: AttributeSet?) : this(context, attrs, 0)
|
||||
|
||||
@SuppressLint("SetTextI18n") constructor(context: Context, attrs: AttributeSet?, defStyleAttr: Int) : super(context, attrs, defStyleAttr) {
|
||||
LayoutInflater.from(context).inflate(R.layout.layout_badcase_collect, this, true)
|
||||
background = ColorDrawable(Color.parseColor("#F0151D41"))
|
||||
isClickable = true
|
||||
layoutParams = ViewGroup.LayoutParams(960.toPixels().toInt(), 1528.toPixels().toInt())
|
||||
close?.onClick {
|
||||
onDismiss?.invoke()
|
||||
}
|
||||
cancel?.also {
|
||||
it.background = shape(solid = Color.parseColor("#3B4577"), radius = 16)
|
||||
it.onClick {
|
||||
onDismiss?.invoke()
|
||||
}
|
||||
}
|
||||
ok?.also {
|
||||
val enabled = gradient(radius = 16.toPixels().toInt(), orientation = GradientDrawable.Orientation.LEFT_RIGHT, centerX = 0.06f, startColor = Color.rgb(35, 146, 252), endColor = Color.rgb(28, 75, 252))
|
||||
val disabled = gradient(radius = 16.toPixels().toInt(), orientation = GradientDrawable.Orientation.LEFT_RIGHT, centerX = 0.06f, startColor = Color.rgb(24, 71, 129), endColor = Color.rgb(21, 46, 129))
|
||||
it.background = object : StateListDrawable() {}.also { itx ->
|
||||
itx.addState(intArrayOf(android.R.attr.state_enabled), enabled)
|
||||
itx.addState(StateSet.WILD_CARD, disabled)
|
||||
}
|
||||
it.onClick {
|
||||
selectCase?.run {
|
||||
scope.launch {
|
||||
onSelect?.invoke(this@run)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
scope.launchWhenCreated {
|
||||
time_of_take_over?.text = "接管时间:${SimpleDateFormat("yyyy.MM.dd HH:mm", Locale.getDefault()).format(record?.toLongTime() ?: System.currentTimeMillis())}"
|
||||
showLoading()
|
||||
presenter.loadBadCases().also {
|
||||
cases = it
|
||||
refresh(it)
|
||||
}
|
||||
hideLoading()
|
||||
}
|
||||
}
|
||||
|
||||
private fun refresh(causes: List<Reason>) {
|
||||
cases = causes
|
||||
rv_take_over?.let {
|
||||
it.layoutManager = LinearLayoutManager(it.context, LinearLayoutManager.VERTICAL, false)
|
||||
it.adapter = object : RecyclerView.Adapter<BadCaseViewHolder>() {
|
||||
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): BadCaseViewHolder = BadCaseViewHolder(LayoutInflater.from(parent.context).inflate(R.layout.layout_badcase_item, parent, false))
|
||||
override fun onBindViewHolder(holder: BadCaseViewHolder, position: Int) {
|
||||
val cases = cases
|
||||
if (cases == null || cases.isEmpty()) {
|
||||
return
|
||||
}
|
||||
if (position >= cases.size) {
|
||||
return
|
||||
}
|
||||
val case = cases[position]
|
||||
holder.bindData(case)
|
||||
}
|
||||
override fun getItemCount(): Int = cases?.size ?: 0
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun showLoading() {
|
||||
pb?.let {
|
||||
it.visibility = View.VISIBLE
|
||||
}
|
||||
}
|
||||
|
||||
private fun hideLoading() {
|
||||
pb?.let {
|
||||
it.visibility = View.INVISIBLE
|
||||
}
|
||||
}
|
||||
|
||||
private inner class BadCaseViewHolder(item: View) : RecyclerView.ViewHolder(item) {
|
||||
|
||||
private val check: ImageView = item.findViewById(R.id.check)
|
||||
private val reason: TextView = item.findViewById(R.id.reason)
|
||||
|
||||
init {
|
||||
check.background = StateListDrawable().also {
|
||||
it.addState(intArrayOf(android.R.attr.state_selected), ContextCompat.getDrawable(itemView.context, R.drawable.icon_ap_badcase_check))
|
||||
it.addState(StateSet.WILD_CARD, ContextCompat.getDrawable(itemView.context, R.drawable.icon_ap_badcase_default))
|
||||
}
|
||||
}
|
||||
|
||||
@SuppressLint("NotifyDataSetChanged")
|
||||
fun bindData(case: Reason) {
|
||||
check.isSelected = case.isChecked
|
||||
reason.text = case.reason ?: ""
|
||||
if (case.isChecked) {
|
||||
ok?.isSelected = true
|
||||
}
|
||||
itemView.onClick {
|
||||
case.isChecked = !case.isChecked
|
||||
selectCase = case
|
||||
cancelOtherChecked(case)
|
||||
ok?.isEnabled = hasCheckedItem()
|
||||
rv_take_over?.adapter?.notifyDataSetChanged()
|
||||
}
|
||||
}
|
||||
|
||||
private fun hasCheckedItem(): Boolean = cases?.find { it.isChecked } != null
|
||||
|
||||
private fun cancelOtherChecked(case: Reason) {
|
||||
val cases = cases
|
||||
if (cases == null || cases.isEmpty()) {
|
||||
return
|
||||
}
|
||||
cases.filterNot { it == case }.forEach {
|
||||
it.isChecked = false
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fun register(record: AutoPilotRecord?, onDismiss: () -> Unit, onSelect:suspend (reason: Reason) -> Unit) {
|
||||
this.record = record
|
||||
this.onDismiss = onDismiss
|
||||
this.onSelect = onSelect
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,24 @@
|
||||
package com.zhjt.mogo_core_function_devatools.badcase.mvp.biz
|
||||
|
||||
import com.zhjt.mogo_core_function_devatools.badcase.api.entity.BadCaseResponse.Reason
|
||||
import com.zhjt.mogo_core_function_devatools.badcase.api.entity.UploadResult
|
||||
import com.zhjt.mogo_core_function_devatools.badcase.repository.db.entity.AutoPilotRecord
|
||||
import kotlinx.coroutines.flow.Flow
|
||||
|
||||
|
||||
internal interface IBadCasePresenter {
|
||||
|
||||
suspend fun loadBadCases(): List<Reason>
|
||||
|
||||
suspend fun updateLastModified(timestamp: Long)
|
||||
|
||||
suspend fun getLastModified(): Long
|
||||
|
||||
suspend fun upload(map: Map<String, String>): UploadResult?
|
||||
|
||||
suspend fun insertRecord(record: AutoPilotRecord)
|
||||
|
||||
suspend fun getUnConsumedRecords(): List<AutoPilotRecord>
|
||||
|
||||
suspend fun deleteRecord(record: AutoPilotRecord)
|
||||
}
|
||||
@@ -1,14 +1,16 @@
|
||||
package com.zhjt.mogo_core_function_devatools.badcase.repository
|
||||
|
||||
import android.util.Log
|
||||
import com.mogo.eagle.core.utilcode.mogo.logger.scene.SceneConstant.Companion.M_DEVA
|
||||
import com.mogo.eagle.core.utilcode.mogo.logger.CallerLogger
|
||||
import com.zhjt.mogo_core_function_devatools.badcase.BadCaseManager
|
||||
import com.zhjt.mogo_core_function_devatools.badcase.repository.net.api.entity.BadCaseResponse.Reason
|
||||
import com.zhjt.mogo_core_function_devatools.badcase.repository.net.api.entity.UploadResult
|
||||
import com.zhjt.mogo_core_function_devatools.badcase.api.entity.BadCaseResponse.Reason
|
||||
import com.zhjt.mogo_core_function_devatools.badcase.api.entity.UploadResult
|
||||
import com.zhjt.mogo_core_function_devatools.badcase.repository.db.BadCaseDbModel
|
||||
import com.zhjt.mogo_core_function_devatools.badcase.repository.db.entity.AutoPilotRecord
|
||||
import com.zhjt.mogo_core_function_devatools.badcase.repository.net.BadCaseNetModel
|
||||
import com.zhjt.mogo_core_function_devatools.badcase.repository.store.BadCaseStore
|
||||
|
||||
|
||||
internal class Repository {
|
||||
|
||||
private val net by lazy {
|
||||
@@ -32,12 +34,12 @@ internal class Repository {
|
||||
}
|
||||
|
||||
suspend fun getLastModified(): Long {
|
||||
Log.d(BadCaseManager.TAG, " --- 3 ----")
|
||||
CallerLogger.d("$M_DEVA${BadCaseManager.TAG}", " --- 3 ----")
|
||||
return store.getLastModified()
|
||||
}
|
||||
|
||||
private fun getBuildIn(): List<Reason> {
|
||||
Log.d(BadCaseManager.TAG, "-- load cases from buildin -- 1 --")
|
||||
CallerLogger.d("$M_DEVA${BadCaseManager.TAG}", "-- load cases from buildin -- 1 --")
|
||||
val data = mutableListOf<Reason>()
|
||||
data += Reason().also {
|
||||
it.id = "1"
|
||||
|
||||
@@ -1,17 +1,18 @@
|
||||
package com.zhjt.mogo_core_function_devatools.badcase.repository.net
|
||||
|
||||
import android.util.Log
|
||||
import com.mogo.eagle.core.utilcode.mogo.logger.scene.SceneConstant.Companion.M_DEVA
|
||||
import com.mogo.eagle.core.utilcode.mogo.logger.CallerLogger
|
||||
import com.mogo.eagle.core.network.MoGoRetrofitFactory
|
||||
import com.zhjt.mogo_core_function_devatools.badcase.BadCaseManager
|
||||
import com.zhjt.mogo_core_function_devatools.badcase.repository.net.api.BadCaseApi
|
||||
import com.zhjt.mogo_core_function_devatools.badcase.repository.net.api.entity.BadCaseResponse
|
||||
import com.zhjt.mogo_core_function_devatools.badcase.repository.net.api.entity.UploadResult
|
||||
import com.zhjt.mogo_core_function_devatools.badcase.api.BadCaseApi
|
||||
import com.zhjt.mogo_core_function_devatools.badcase.api.entity.BadCaseResponse
|
||||
import com.zhjt.mogo_core_function_devatools.badcase.api.entity.UploadResult
|
||||
import com.zhjt.mogo_core_function_devatools.badcase.consts.BadCaseHost
|
||||
|
||||
internal class BadCaseNetModel {
|
||||
|
||||
suspend fun get(): BadCaseResponse? = try {
|
||||
Log.d(BadCaseManager.TAG, "-- load cases from net -- 1 --")
|
||||
CallerLogger.d("$M_DEVA${BadCaseManager.TAG}", "-- load cases from net -- 1 --")
|
||||
MoGoRetrofitFactory
|
||||
.getInstance(BadCaseHost.getHost())
|
||||
.create(BadCaseApi::class.java)
|
||||
@@ -21,10 +22,10 @@ internal class BadCaseNetModel {
|
||||
it.isSuccessful && body != null && (body.code == 0 || body.code == 200)
|
||||
}
|
||||
?.body()?.also {
|
||||
Log.d(BadCaseManager.TAG, "-- load cases from net -- 2 --")
|
||||
CallerLogger.d("$M_DEVA${BadCaseManager.TAG}", "-- load cases from net -- 2 --")
|
||||
}
|
||||
} catch (t: Throwable) {
|
||||
Log.d(BadCaseManager.TAG, "-- load cases from net -- 3 --")
|
||||
CallerLogger.d("$M_DEVA${BadCaseManager.TAG}", "-- load cases from net -- 3 --")
|
||||
null
|
||||
}
|
||||
|
||||
|
||||
@@ -1,16 +1,20 @@
|
||||
package com.zhjt.mogo_core_function_devatools.badcase.repository.store
|
||||
|
||||
import android.util.Log
|
||||
import androidx.datastore.core.DataStore
|
||||
import androidx.datastore.core.DataStoreFactory
|
||||
import androidx.datastore.core.Serializer
|
||||
import com.mogo.eagle.core.utilcode.mogo.logger.scene.SceneConstant.Companion.M_DEVA
|
||||
import com.mogo.eagle.core.utilcode.mogo.logger.CallerLogger
|
||||
import com.mogo.eagle.core.utilcode.util.Utils
|
||||
import com.zhjt.mogo_core_function_devatools.badcase.BadCaseManager
|
||||
import com.zhjt.mogo_core_function_devatools.badcase.repository.net.api.entity.BadCaseResponse.Reason
|
||||
import com.zhjt.mogo_core_function_devatools.badcase.api.entity.BadCaseResponse.Reason
|
||||
import com.zhjt.mogo_core_function_devatools.badcase.generated.BadCauses
|
||||
import com.zhjt.mogo_core_function_devatools.badcase.generated.Cause
|
||||
import kotlinx.coroutines.*
|
||||
import kotlinx.coroutines.flow.*
|
||||
import kotlinx.coroutines.FlowPreview
|
||||
import kotlinx.coroutines.flow.catch
|
||||
import kotlinx.coroutines.flow.firstOrNull
|
||||
import kotlinx.coroutines.flow.map
|
||||
import kotlinx.coroutines.suspendCancellableCoroutine
|
||||
import java.io.File
|
||||
import java.io.IOException
|
||||
import java.io.InputStream
|
||||
@@ -24,7 +28,7 @@ internal object BadCaseStore {
|
||||
get() = BadCauses.getDefaultInstance()
|
||||
|
||||
override suspend fun readFrom(input: InputStream): BadCauses = suspendCancellableCoroutine {
|
||||
Log.d(BadCaseManager.TAG, "--- readFrom ---")
|
||||
CallerLogger.d("$M_DEVA${BadCaseManager.TAG}", "--- readFrom ---")
|
||||
it.invokeOnCancellation {
|
||||
Thread.currentThread().interrupt()
|
||||
}
|
||||
@@ -35,26 +39,32 @@ internal object BadCaseStore {
|
||||
}
|
||||
}
|
||||
|
||||
override suspend fun writeTo(t: BadCauses, output: OutputStream) = suspendCancellableCoroutine<Unit> {
|
||||
it.invokeOnCancellation {
|
||||
Thread.currentThread().interrupt()
|
||||
override suspend fun writeTo(t: BadCauses, output: OutputStream) =
|
||||
suspendCancellableCoroutine<Unit> {
|
||||
it.invokeOnCancellation {
|
||||
Thread.currentThread().interrupt()
|
||||
}
|
||||
try {
|
||||
t.writeTo(output)
|
||||
it.resumeWith(Result.success(Unit))
|
||||
} catch (t: Throwable) {
|
||||
it.resumeWith(Result.failure(t))
|
||||
}
|
||||
}
|
||||
try {
|
||||
t.writeTo(output)
|
||||
it.resumeWith(Result.success(Unit))
|
||||
} catch (t: Throwable) {
|
||||
it.resumeWith(Result.failure(t))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private val store: DataStore<BadCauses> by lazy {
|
||||
DataStoreFactory.create(serializer = serializer) { File(Utils.getApp().filesDir, "bad_cases.pb") }
|
||||
DataStoreFactory.create(serializer = serializer) {
|
||||
File(
|
||||
Utils.getApp().filesDir,
|
||||
"bad_cases.pb"
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
suspend fun updateRecords(reasons: List<Reason>): BadCauses {
|
||||
Log.d(BadCaseManager.TAG, "--- updateRecords ---")
|
||||
CallerLogger.d("$M_DEVA${BadCaseManager.TAG}", "--- updateRecords ---")
|
||||
val data = mutableListOf<Cause>()
|
||||
reasons.forEach { itx ->
|
||||
data += Cause.newBuilder().let {
|
||||
@@ -69,14 +79,14 @@ internal object BadCaseStore {
|
||||
}
|
||||
|
||||
suspend fun updateLastModified(timestamp: Long): BadCauses {
|
||||
Log.d(BadCaseManager.TAG, "--- updateLastModified ---")
|
||||
CallerLogger.d("$M_DEVA${BadCaseManager.TAG}", "--- updateLastModified ---")
|
||||
return store.updateData { itx ->
|
||||
itx.toBuilder().setLastModified(timestamp).build()
|
||||
}
|
||||
itx.toBuilder().setLastModified(timestamp).build()
|
||||
}
|
||||
}
|
||||
|
||||
suspend fun getLastModified(): Long {
|
||||
Log.d(BadCaseManager.TAG, " --- 4 ----")
|
||||
CallerLogger.d("$M_DEVA${BadCaseManager.TAG}", " --- 4 ----")
|
||||
return store
|
||||
.data
|
||||
.catch {
|
||||
@@ -92,7 +102,7 @@ internal object BadCaseStore {
|
||||
|
||||
@OptIn(FlowPreview::class)
|
||||
suspend fun records(): List<Reason> {
|
||||
Log.d(BadCaseManager.TAG, "-- load cases from pb -- 1 -- ")
|
||||
CallerLogger.d("$M_DEVA${BadCaseManager.TAG}", "-- load cases from pb -- 1 -- ")
|
||||
val causes = store.data.firstOrNull()
|
||||
return causes?.dataList?.map {
|
||||
Reason().also { itx ->
|
||||
|
||||
@@ -10,13 +10,14 @@ import com.mogo.commons.AbsMogoApplication
|
||||
import com.mogo.commons.debug.DebugConfig
|
||||
import com.mogo.eagle.core.data.app.AppConfigInfo
|
||||
import com.mogo.eagle.core.data.constants.MoGoConfig
|
||||
import com.mogo.eagle.core.utilcode.mogo.logger.scene.SceneConstant.Companion.M_DEVA
|
||||
import com.mogo.eagle.core.function.call.autopilot.CallerAutoPilotManager
|
||||
import com.mogo.eagle.core.function.call.devatools.CallerDevaToolsListenerManager
|
||||
import com.mogo.eagle.core.utilcode.mogo.logger.CallerLogger
|
||||
import com.mogo.eagle.core.utilcode.mogo.logger.LogLevel
|
||||
import com.mogo.eagle.core.utilcode.mogo.logger.Logger
|
||||
import com.mogo.eagle.core.utilcode.mogo.storage.SharedPrefsMgr
|
||||
import com.mogo.eagle.core.utilcode.mogo.toast.TipToast
|
||||
import com.mogo.eagle.core.utilcode.util.LogUtils
|
||||
import com.mogo.eagle.core.utilcode.util.ThreadUtils
|
||||
import com.mogo.module.common.MogoApisHandler
|
||||
import com.mogo.service.cloud.socket.IMogoOnMessageListener
|
||||
@@ -66,9 +67,9 @@ object MogoLogCatchManager : IMogoOnMessageListener<RemoteLogPushContent>, Handl
|
||||
}
|
||||
startCatchLog(logTime)
|
||||
} else {
|
||||
Logger.d(
|
||||
TAG,
|
||||
"logCheck logger : $logger , logCatchDuration : $logCatchDuration"
|
||||
CallerLogger.d(
|
||||
"$M_DEVA$TAG",
|
||||
"logCheck Logger : $logger , logCatchDuration : $logCatchDuration"
|
||||
)
|
||||
}
|
||||
}
|
||||
@@ -79,7 +80,7 @@ object MogoLogCatchManager : IMogoOnMessageListener<RemoteLogPushContent>, Handl
|
||||
|
||||
override fun onMsgReceived(obj: RemoteLogPushContent?) {
|
||||
obj?.let {
|
||||
Logger.d(TAG, "收到push消息: $obj")
|
||||
CallerLogger.d("$M_DEVA$TAG", "收到push消息: $obj")
|
||||
when (obj.type) {
|
||||
START_CATCH_LOG -> if (!catchingList.contains(obj.pkgName)) {
|
||||
startCatchLog(obj)
|
||||
@@ -106,7 +107,7 @@ object MogoLogCatchManager : IMogoOnMessageListener<RemoteLogPushContent>, Handl
|
||||
if (catchingList.contains(MANUAL_CATCH_PKG_NAME)) {
|
||||
TipToast.shortTip("已经在抓取日志了,请稍后再试")
|
||||
} else {
|
||||
Logger.d(TAG, "开始抓取日志==== duration : $duration")
|
||||
CallerLogger.d("$M_DEVA$TAG", "开始抓取日志==== duration : $duration")
|
||||
manualContent.type = START_CATCH_LOG
|
||||
manualContent.duration = duration
|
||||
startCatchLog(manualContent)
|
||||
@@ -114,7 +115,7 @@ object MogoLogCatchManager : IMogoOnMessageListener<RemoteLogPushContent>, Handl
|
||||
}
|
||||
|
||||
fun stopCatchLog() {
|
||||
Logger.d(TAG, "结束抓取日志====")
|
||||
CallerLogger.d("$M_DEVA$TAG", "结束抓取日志====")
|
||||
manualContent.type = STOP_CATCH_LOG
|
||||
stopCatchLog(manualContent)
|
||||
}
|
||||
@@ -166,22 +167,18 @@ object MogoLogCatchManager : IMogoOnMessageListener<RemoteLogPushContent>, Handl
|
||||
* 放开Logger的限制
|
||||
*/
|
||||
private fun openLoggerLevel() {
|
||||
LogUtils.getConfig().isLogSwitch = true
|
||||
Logger.init(LogLevel.DEBUG)
|
||||
MoGoAiCloudClient.getInstance().aiCloudClientConfig.isShowDebugLog = true
|
||||
CallerAutoPilotManager.setEnableLog(true)
|
||||
CallerAutoPilotManager.setIsWriteLog(true)
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据状态收紧Logger的限制
|
||||
*/
|
||||
private fun closeLoggerLevel() {
|
||||
LogUtils.getConfig().isLogSwitch = false
|
||||
Logger.init(if (DebugConfig.isDebug()) LogLevel.DEBUG else LogLevel.OFF)
|
||||
MoGoAiCloudClient.getInstance().aiCloudClientConfig.isShowDebugLog = false
|
||||
CallerAutoPilotManager.setEnableLog(false)
|
||||
CallerAutoPilotManager.setIsWriteLog(false)
|
||||
}
|
||||
|
||||
override fun onError(errorCount: Int) {
|
||||
|
||||
@@ -2,14 +2,14 @@ package com.zhjt.mogo_core_function_devatools.trace
|
||||
|
||||
import android.content.Context
|
||||
import com.mogo.cloud.passport.MoGoAiCloudClientConfig
|
||||
import com.mogo.eagle.core.data.deva.chain.ChainConstant
|
||||
import com.mogo.eagle.core.data.deva.chain.ChainLogParam
|
||||
import com.mogo.eagle.core.utilcode.mogo.logger.Logger
|
||||
import com.mogo.eagle.core.data.chain.ChainConstant
|
||||
import com.mogo.eagle.core.data.chain.ChainLogParam
|
||||
import com.mogo.eagle.core.utilcode.mogo.logger.scene.SceneConstant.Companion.M_DEVA
|
||||
import com.mogo.eagle.core.utilcode.mogo.logger.CallerLogger
|
||||
import com.mogo.eagle.core.utilcode.util.DeviceUtils
|
||||
import com.mogo.eagle.core.utilcode.util.Utils
|
||||
import com.zhidao.loglib.fw.FileWriteManager
|
||||
import com.zhidao.loglib.fw.FwBuild
|
||||
import com.zhjt.mogo_core_function_devatools.DevaToolsProvider.Companion.MODULE_NAME
|
||||
import com.zhjt.service.chain.core.ChainTraceStarter
|
||||
|
||||
class TraceManager {
|
||||
@@ -19,6 +19,8 @@ class TraceManager {
|
||||
|
||||
companion object {
|
||||
|
||||
const val TAG = "TraceManager"
|
||||
|
||||
val traceManager by lazy(LazyThreadSafetyMode.SYNCHRONIZED) {
|
||||
TraceManager()
|
||||
}
|
||||
@@ -51,7 +53,7 @@ class TraceManager {
|
||||
map.forEach { (type, param) ->
|
||||
val fwBuild = this.fwBuildMap[type]
|
||||
fwBuild?.let {
|
||||
Logger.d(MODULE_NAME, "param : ${param.des} , record : ${param.record}")
|
||||
CallerLogger.d("$M_DEVA$TAG", "param : ${param.des} , record : ${param.record}")
|
||||
it.isRecord = param.record
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user