[BadCase]BadCase记录添加持久化逻辑
This commit is contained in:
@@ -39,7 +39,7 @@ class AutoPilotBadCaseTest {
|
||||
.onEach {
|
||||
delay(TimeUnit.SECONDS.toMillis(5))
|
||||
f.onAutopilotRecordResult(AutoPilotRecordResult().also {
|
||||
it.diskFree = 100 + index
|
||||
it.diskFree = (100 + index).toLong()
|
||||
it.duration = 60.0
|
||||
it.fileName = "/user/general/record_$index.log"
|
||||
it.id = 10 + index
|
||||
@@ -70,7 +70,7 @@ class AutoPilotBadCaseTest {
|
||||
delay(Random(20).nextLong())
|
||||
}
|
||||
f.onAutopilotRecordResult(AutoPilotRecordResult().also {
|
||||
it.diskFree = 100 + index
|
||||
it.diskFree = (100 + index).toLong()
|
||||
it.duration = 60.0
|
||||
it.fileName = "/user/general/record_$index.log"
|
||||
it.id = 10 + index
|
||||
@@ -101,7 +101,7 @@ class AutoPilotBadCaseTest {
|
||||
.onEach {
|
||||
delay(TimeUnit.SECONDS.toMillis(20))
|
||||
f.onAutopilotRecordResult(AutoPilotRecordResult().also {
|
||||
it.diskFree = 100 + index
|
||||
it.diskFree = (100 + index).toLong()
|
||||
it.duration = 60.0
|
||||
it.fileName = "/user/general/record_$index.log"
|
||||
it.id = 10 + index
|
||||
|
||||
@@ -54,6 +54,11 @@ dependencies {
|
||||
|
||||
kapt rootProject.ext.dependencies.aroutercompiler
|
||||
|
||||
kapt rootProject.ext.dependencies.androidxroomcompiler
|
||||
implementation rootProject.ext.dependencies.androidxroomruntime
|
||||
implementation rootProject.ext.dependencies.androidxroomktx
|
||||
|
||||
|
||||
if (Boolean.valueOf(USE_MAVEN_PACKAGE)) {
|
||||
implementation rootProject.ext.dependencies.androidxrecyclerview
|
||||
implementation rootProject.ext.dependencies.modulecommon
|
||||
|
||||
@@ -7,7 +7,6 @@ import android.text.TextUtils
|
||||
import android.util.Log
|
||||
import android.view.*
|
||||
import android.view.animation.OvershootInterpolator
|
||||
import androidx.annotation.VisibleForTesting
|
||||
import androidx.lifecycle.lifecycleScope
|
||||
import com.alibaba.android.arouter.facade.annotation.Route
|
||||
import com.mogo.cloud.passport.MoGoAiCloudClientConfig
|
||||
@@ -38,6 +37,7 @@ import com.mogo.eagle.core.function.hmi.ui.notice.NoticeNormalBannerView
|
||||
import com.mogo.eagle.core.function.hmi.ui.setting.DebugSettingView
|
||||
import com.mogo.eagle.core.function.hmi.ui.tools.AutoPilotAndCheckView
|
||||
import com.mogo.eagle.core.function.hmi.ui.tools.AutoPilotBadCaseView
|
||||
import com.mogo.eagle.core.function.hmi.ui.tools.Repository
|
||||
import com.mogo.eagle.core.function.hmi.ui.tools.post
|
||||
import com.mogo.eagle.core.function.hmi.ui.widget.V2XNotificationView
|
||||
import com.mogo.eagle.core.utilcode.kotlin.onClick
|
||||
@@ -92,7 +92,7 @@ class MoGoHmiFragment : MvpFragment<MoGoWarningContract.View?, WaringPresenter?>
|
||||
|
||||
companion object {
|
||||
private const val MSG_WHAT_DISMISS_BAD_CASE_ENTRY = 0x1010
|
||||
private val DURATION_FOR_DISMISS = TimeUnit.HOURS.toMillis(4)
|
||||
private val CASE_EXPIRE_DURATION = TimeUnit.HOURS.toMillis(4)
|
||||
}
|
||||
|
||||
@ExperimentalCoroutinesApi
|
||||
@@ -105,7 +105,7 @@ class MoGoHmiFragment : MvpFragment<MoGoWarningContract.View?, WaringPresenter?>
|
||||
val entrance = autoPilotBadCaseEntrance
|
||||
val old = entrance?.getTag(R.id.autopilot_badcase_record) as? AutoPilotRecordResult
|
||||
if (entrance == null || old == null || old.consumed) {
|
||||
Logger.d("QQQ", "-- step -- 1 --")
|
||||
Log.d("QQQ", "-- step -- 1 --")
|
||||
var oldT = try {
|
||||
old?.timestamp?.takeIf { it.isNotBlank() }?.let {
|
||||
SimpleDateFormat("yyyy-MM-dd-HH-mm-ss", Locale.getDefault()).parse(it)?.time ?: 0L
|
||||
@@ -125,17 +125,17 @@ class MoGoHmiFragment : MvpFragment<MoGoWarningContract.View?, WaringPresenter?>
|
||||
0L
|
||||
}
|
||||
|
||||
if (oldT == 0L || (newT > 0L && (newT - oldT > 0L) && (newT - oldT) < DURATION_FOR_DISMISS)) {
|
||||
Logger.d("QQQ", "-- step -- 2 --")
|
||||
if (oldT == 0L || (newT > 0L && (newT - oldT > 0L) && (newT - oldT) < CASE_EXPIRE_DURATION)) {
|
||||
Log.d("QQQ", "-- step -- 2 --")
|
||||
record?.takeIf { it.key != old?.key && it.timestamp != old?.timestamp }?.also {
|
||||
Logger.d("QQQ", "record: [$record] is displaying and consuming ~~~" )
|
||||
Log.d("QQQ", "record: [$record] is displaying and consuming ~~~" )
|
||||
showBadCaseEntrance(it)
|
||||
}
|
||||
continue
|
||||
}
|
||||
|
||||
while (oldT != 0L && newT != 0L && (newT - oldT) >= DURATION_FOR_DISMISS) {
|
||||
Logger.d("QQQ", "record: [$record] has been discarded, because it has been timeout." )
|
||||
while (oldT != 0L && newT != 0L && (newT - oldT) >= CASE_EXPIRE_DURATION) {
|
||||
Log.d("QQQ", "record: [$record] has been discarded, because it has been timeout." )
|
||||
oldT = newT
|
||||
newT = try {
|
||||
it.receive()?.also {
|
||||
@@ -149,11 +149,11 @@ class MoGoHmiFragment : MvpFragment<MoGoWarningContract.View?, WaringPresenter?>
|
||||
}
|
||||
}
|
||||
record?.takeIf { it.key != old?.key && it.timestamp != old?.timestamp }?.also {
|
||||
Logger.d("QQQ", "record: [$record] is displaying for rest ..." )
|
||||
Log.d("QQQ", "record: [$record] is displaying for rest ..." )
|
||||
showBadCaseEntrance(it)
|
||||
}
|
||||
} else {
|
||||
Logger.d("QQQ", "record: [$old] hasn't been consumed~~~~" )
|
||||
Log.d("QQQ", "record: [$old] hasn't been consumed~~~~" )
|
||||
}
|
||||
} finally {
|
||||
delay(1000)
|
||||
@@ -169,10 +169,19 @@ class MoGoHmiFragment : MvpFragment<MoGoWarningContract.View?, WaringPresenter?>
|
||||
if (it.what == MSG_WHAT_DISMISS_BAD_CASE_ENTRY) {
|
||||
val entrance = autoPilotBadCaseEntrance
|
||||
if (entrance != null && entrance.visibility == View.VISIBLE) {
|
||||
Logger.d(TAG, "${DURATION_FOR_DISMISS}毫秒后BadCase入口消失")
|
||||
(entrance.getTag(R.id.autopilot_badcase_record) as? AutoPilotRecordResult)?.let { itx ->
|
||||
itx.consumed = true
|
||||
val record = entrance.getTag(R.id.autopilot_badcase_record) as? AutoPilotRecordResult
|
||||
record?.consumed = true
|
||||
record?.let { itx ->
|
||||
lifecycleScope.launch(Dispatchers.IO) {
|
||||
try {
|
||||
val i = Repository.dao().deleteRecord(itx)
|
||||
Log.d("QQQ", "delete result: $i")
|
||||
} catch (t: Throwable) {
|
||||
Log.d("QQQ", "---- delete error: ${t.message}")
|
||||
}
|
||||
}
|
||||
}
|
||||
dismissBadCaseFloatView()
|
||||
entrance.visibility = View.GONE
|
||||
}
|
||||
return@Callback true
|
||||
@@ -212,18 +221,41 @@ class MoGoHmiFragment : MvpFragment<MoGoWarningContract.View?, WaringPresenter?>
|
||||
}
|
||||
}
|
||||
|
||||
@ExperimentalCoroutinesApi
|
||||
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
||||
super.onViewCreated(view, savedInstanceState)
|
||||
CallerAutopilotIdentifyListenerManager.addListener(TAG, this)
|
||||
lifecycleScope.launchWhenResumed {
|
||||
withContext(Dispatchers.IO) {
|
||||
val dao = Repository.dao()
|
||||
try {
|
||||
dao.getAllUnConsumedRecords()?.forEach {
|
||||
channel.send(it)
|
||||
}
|
||||
} catch (t: Throwable) {
|
||||
t.printStackTrace()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ExperimentalCoroutinesApi
|
||||
override fun onAutopilotRecordResult(record: AutoPilotRecordResult?) {
|
||||
record ?: return
|
||||
Logger.d("QQQ", "onAutopilotRecordResult:$record")
|
||||
Log.d("QQQ", "onAutopilotRecordResult:$record")
|
||||
if (record.type == 1 && record.stat == 100) {
|
||||
lifecycleScope.launchWhenResumed {
|
||||
channel.send(record)
|
||||
withContext(Dispatchers.IO) {
|
||||
val dao = Repository.dao()
|
||||
try {
|
||||
dao.insertRecord(record)
|
||||
} catch (t: Throwable) {
|
||||
t.printStackTrace()
|
||||
}
|
||||
record.also {
|
||||
channel.send(it)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -233,15 +265,15 @@ class MoGoHmiFragment : MvpFragment<MoGoWarningContract.View?, WaringPresenter?>
|
||||
CallerAutopilotIdentifyListenerManager.removeListener(TAG)
|
||||
}
|
||||
|
||||
@VisibleForTesting
|
||||
fun showBadCaseEntrance(record: AutoPilotRecordResult) {
|
||||
Logger.d("QQQ", "showBadCaseEntrance:$record")
|
||||
private fun showBadCaseEntrance(record: AutoPilotRecordResult) {
|
||||
Log.d("QQQ", "showBadCaseEntrance:$record")
|
||||
lifecycleScope.launch {
|
||||
if (vs_bad_case_entrance?.parent != null) {
|
||||
val inflateView = vs_bad_case_entrance.inflate()
|
||||
autoPilotBadCaseEntrance = inflateView
|
||||
}
|
||||
val entrance = autoPilotBadCaseEntrance
|
||||
Log.d("QQQ", "show --- 1 ----")
|
||||
if (entrance != null) {
|
||||
if (entrance.visibility != View.VISIBLE) {
|
||||
entrance.visibility = View.VISIBLE
|
||||
@@ -258,7 +290,7 @@ class MoGoHmiFragment : MvpFragment<MoGoWarningContract.View?, WaringPresenter?>
|
||||
}
|
||||
|
||||
private fun showBadCasesFloat(dismiss: (() -> Unit)?) {
|
||||
Logger.d("QQQ", "showBadCaseToolsFloat")
|
||||
Log.d("QQQ", "showBadCaseToolsFloat")
|
||||
context?.let { it ->
|
||||
if (autoPilotToolsFloat == null) {
|
||||
if (autoPilotBadCaseView == null) {
|
||||
@@ -286,7 +318,7 @@ class MoGoHmiFragment : MvpFragment<MoGoWarningContract.View?, WaringPresenter?>
|
||||
if (response.isSuccessful) {
|
||||
val body = response.body()
|
||||
if (body == null) {
|
||||
Logger.e("QQQ", "返回的body是空的~~~")
|
||||
Log.e("QQQ", "返回的body是空的~~~")
|
||||
return@launch
|
||||
}
|
||||
if (body.code == 200) {
|
||||
@@ -298,15 +330,24 @@ class MoGoHmiFragment : MvpFragment<MoGoWarningContract.View?, WaringPresenter?>
|
||||
record?.fileName,
|
||||
it.id, it.reason)
|
||||
ToastUtils.showShort("接管反馈成功~")
|
||||
record?.consumed = true
|
||||
record?.also {
|
||||
it.consumed = true
|
||||
withContext(Dispatchers.IO) {
|
||||
try {
|
||||
Repository.dao().deleteRecord(record)
|
||||
} catch (t: Throwable) {
|
||||
Log.d("QQQ", "---- delete error 2: ${t.message}")
|
||||
}
|
||||
}
|
||||
}
|
||||
return@launch
|
||||
}
|
||||
Logger.e("QQQ", "fail:${body}")
|
||||
Log.e("QQQ", "fail:${body}")
|
||||
}
|
||||
} catch (t: Throwable) {
|
||||
t.printStackTrace()
|
||||
ToastUtils.showShort("网络请求失败,请尝试联网~")
|
||||
Logger.e("QQQ", "exception:${t.message}")
|
||||
Log.e("QQQ", "exception:${t.message}")
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -354,7 +395,7 @@ class MoGoHmiFragment : MvpFragment<MoGoWarningContract.View?, WaringPresenter?>
|
||||
|
||||
private fun dismissBadCaseEntryAfterSomeTime() {
|
||||
handler.removeMessages(MSG_WHAT_DISMISS_BAD_CASE_ENTRY)
|
||||
handler.sendEmptyMessageDelayed(MSG_WHAT_DISMISS_BAD_CASE_ENTRY, DURATION_FOR_DISMISS)
|
||||
handler.sendEmptyMessageDelayed(MSG_WHAT_DISMISS_BAD_CASE_ENTRY, CASE_EXPIRE_DURATION)
|
||||
}
|
||||
|
||||
private fun showToolsFloat() {
|
||||
|
||||
@@ -20,9 +20,11 @@ import androidx.constraintlayout.widget.ConstraintLayout
|
||||
import androidx.core.content.ContextCompat
|
||||
import androidx.recyclerview.widget.LinearLayoutManager
|
||||
import androidx.recyclerview.widget.RecyclerView
|
||||
import androidx.room.*
|
||||
import com.google.gson.annotations.Expose
|
||||
import com.mogo.commons.debug.DebugConfig
|
||||
import com.mogo.commons.debug.DebugConfig.getNetMode
|
||||
import com.mogo.eagle.core.data.autopilot.AutoPilotRecordResult
|
||||
import com.mogo.eagle.core.function.hmi.R
|
||||
import com.mogo.eagle.core.function.hmi.ui.tools.BadCaseEntity.Reason
|
||||
import com.mogo.eagle.core.network.RetrofitFactory
|
||||
@@ -41,10 +43,41 @@ import retrofit2.http.POST
|
||||
import kotlin.Result.Companion.failure
|
||||
import kotlin.Result.Companion.success
|
||||
|
||||
|
||||
private typealias OnDismissCallback = () -> Unit
|
||||
private typealias OnSelectCallback = (Reason) -> Unit
|
||||
|
||||
|
||||
object Repository {
|
||||
|
||||
fun dao(): Dao {
|
||||
return Room.databaseBuilder(Utils.getApp(), RecordDb::class.java, "bad-cases").build().dao()
|
||||
}
|
||||
|
||||
@Database(entities = [
|
||||
AutoPilotRecordResult::class
|
||||
],
|
||||
version = 1,
|
||||
exportSchema = false)
|
||||
abstract class RecordDb : RoomDatabase() {
|
||||
abstract fun dao(): Dao
|
||||
}
|
||||
|
||||
@androidx.room.Dao
|
||||
interface Dao {
|
||||
|
||||
@Transaction
|
||||
@Insert(onConflict = OnConflictStrategy.REPLACE)
|
||||
suspend fun insertRecord(record: AutoPilotRecordResult): Long
|
||||
|
||||
@Transaction
|
||||
@Delete
|
||||
suspend fun deleteRecord(record: AutoPilotRecordResult): Int
|
||||
|
||||
@Query("SELECT * FROM record ORDER BY timestamp ASC")
|
||||
suspend fun getAllUnConsumedRecords(): List<AutoPilotRecordResult>?
|
||||
}
|
||||
}
|
||||
|
||||
interface BadCaseApi {
|
||||
|
||||
@FormUrlEncoded
|
||||
|
||||
@@ -50,7 +50,9 @@ dependencies {
|
||||
|
||||
implementation rootProject.ext.dependencies.arouter
|
||||
kapt rootProject.ext.dependencies.aroutercompiler
|
||||
|
||||
implementation rootProject.ext.dependencies.androidxroomruntime
|
||||
implementation rootProject.ext.dependencies.androidxroomktx
|
||||
kapt rootProject.ext.dependencies.androidxroomcompiler
|
||||
if (Boolean.valueOf(USE_MAVEN_PACKAGE)) {
|
||||
implementation rootProject.ext.dependencies.mogo_core_res
|
||||
} else {
|
||||
|
||||
@@ -1,13 +1,18 @@
|
||||
package com.mogo.eagle.core.data.autopilot
|
||||
|
||||
import androidx.room.ColumnInfo
|
||||
import androidx.room.Entity
|
||||
import androidx.room.PrimaryKey
|
||||
import java.text.SimpleDateFormat
|
||||
import java.util.*
|
||||
|
||||
|
||||
|
||||
@Entity(tableName = "record")
|
||||
class AutoPilotRecordResult {
|
||||
|
||||
/**
|
||||
* 磁盘可用空间(M)
|
||||
*/
|
||||
@ColumnInfo(name = "disk_free")
|
||||
var diskFree: Long = 0
|
||||
|
||||
/**
|
||||
@@ -19,6 +24,7 @@ class AutoPilotRecordResult {
|
||||
/**
|
||||
* 保存的文件名
|
||||
*/
|
||||
@ColumnInfo(name = "file_name")
|
||||
var fileName: String? = ""
|
||||
|
||||
|
||||
@@ -27,7 +33,6 @@ class AutoPilotRecordResult {
|
||||
*/
|
||||
var note: String? = ""
|
||||
|
||||
|
||||
/**
|
||||
* 域控制器定义的bag key
|
||||
*/
|
||||
@@ -54,26 +59,23 @@ class AutoPilotRecordResult {
|
||||
*/
|
||||
var id: Int = 0
|
||||
|
||||
|
||||
/**
|
||||
* 时间戳,格式:YYYY-MM-DD-hh-mm-ss
|
||||
*/
|
||||
var timestamp: String? = ""
|
||||
@PrimaryKey
|
||||
var timestamp: String = SimpleDateFormat("yyyy-MM-dd-HH-mm-ss", Locale.getDefault()).format(Date())
|
||||
|
||||
/**
|
||||
* 此次采集数据总大小(M)
|
||||
*/
|
||||
var total: Long? = 0
|
||||
|
||||
|
||||
/**
|
||||
* 记录此条数据是否已消费
|
||||
*/
|
||||
|
||||
@Volatile
|
||||
var consumed: Boolean = false
|
||||
|
||||
|
||||
override fun toString(): String {
|
||||
return "AutoPilotRecordResult(diskFree=$diskFree, duration=$duration, fileName=$fileName, note=$note, key=$key, stat=$stat, type=$type, id=$id, timestamp=$timestamp, total=$total)"
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user