Merge branch 'dev_robotaxi-d_230912_6.1.0' of gitlab.zhidaoauto.com:SCA/L4HA/AndroidApp/MoGoEagleEye into dev_robotaxi-d_230912_6.1.0

This commit is contained in:
xinfengkun
2023-09-25 15:09:12 +08:00
1542 changed files with 77840 additions and 7659 deletions

View File

@@ -23,9 +23,6 @@ import com.mogo.eagle.core.function.hmi.R;
import com.mogo.eagle.core.function.hmi.ui.utils.SearchCriteria;
import com.mogo.eagle.core.function.hmi.ui.utils.TagColorUtil;
import me.jessyan.autosize.AutoSizeCompat;
public class LogItemAdapter extends AbsRecyclerAdapter<AbsViewBinder<LogLine>, LogLine> implements Filterable {
public LogItemAdapter(Context context) {

View File

@@ -2,6 +2,7 @@ package com.mogo.eagle.core.function.hmi.ui.map
import android.annotation.SuppressLint
import android.content.Context
import android.os.Looper
import android.view.View
import android.widget.ImageView
import android.widget.ProgressBar
@@ -10,16 +11,16 @@ import androidx.constraintlayout.widget.ConstraintLayout
import androidx.core.content.ContextCompat
import com.mogo.eagle.core.data.map.MogoLocation
import com.mogo.eagle.core.function.call.hmi.CallerHmiListenerManager
import com.mogo.eagle.core.function.call.map.CallerMapUIServiceManager
import com.mogo.eagle.core.function.hmi.R
import com.mogo.eagle.core.function.hmi.dialog.BaseFloatDialog
import com.mogo.map.hdcache.IHdCacheListener
import com.mogo.eagle.core.utilcode.util.ThreadUtils
import com.mogo.map.MogoData.Companion.mogoMapData
import me.jessyan.autosize.utils.AutoSizeUtils
/**
* 离线地图缓存
*/
class OfflineMapDialog(context: Context): BaseFloatDialog(context) {
class OfflineMapDialog(context: Context) : BaseFloatDialog(context) {
private var roundRootLayout: ConstraintLayout? = null
private var offlineTitleView: TextView? = null
@@ -86,37 +87,29 @@ class OfflineMapDialog(context: Context): BaseFloatDialog(context) {
okView?.setOnClickListener {
if (isLoading) {
CallerMapUIServiceManager.cancelDownloadCacheData()
mogoMapData.get()?.cancelDownloadCacheData()
}
dismiss()
}
}
private fun cacheHDDataByCityByLonLat() {
CallerMapUIServiceManager.cacheHDDataByCityByLonLat(object : IHdCacheListener {
override fun onMapHdCacheProgress(cityId: Int, progress: Double) {
mogoMapData.get()?.cacheHDDataByCityByLonLat(location!!, { _, progress ->
updateProgress(progress.toInt())
}, { _, state ->
if (state == 0) {// 失败
showNewContent(isLoading = false, false)
}
override fun onMapHdCacheResult(cityId: Int, state: Int) {
if (state == 0) {// 失败
showNewContent(isLoading = false, false)
}
}
}, location!!)
})
}
private fun cacheHDOfflineData() {
if (location == null) {// 拿到了高德地图的cityCode
CallerMapUIServiceManager.cacheHDDataByCity(object : IHdCacheListener {
override fun onMapHdCacheProgress(cityId: Int, progress: Double) {
updateProgress(progress.toInt())
}
override fun onMapHdCacheResult(cityId: Int, state: Int) {
if (state == 0) {// 失败
showNewContent(isLoading = false, false)
}
mogoMapData.get()?.cacheHDDataByCity({ _, progress ->
updateProgress(progress.toInt())
}, { _, state ->
if (state == 0) {// 失败
showNewContent(isLoading = false, false)
}
})
} else {// 只拿到了高精的经纬度
@@ -176,15 +169,18 @@ class OfflineMapDialog(context: Context): BaseFloatDialog(context) {
isSuccess -> {
okView?.visibility = View.VISIBLE
okView?.text = context.resources.getString(R.string.ok_tip)
offlineTitleView?.text = context.resources.getString(R.string.offline_download_success)
offlineTitleView?.text =
context.resources.getString(R.string.offline_download_success)
progressBar?.visibility = View.GONE
downloadPercentView?.visibility = View.GONE
downloadResultImg?.background = ContextCompat.getDrawable(context, R.drawable.download_success_icon)
downloadResultImg?.background =
ContextCompat.getDrawable(context, R.drawable.download_success_icon)
}
else -> {
isRetry = true
isConfirm = false
offlineTitleView?.text = context.resources.getString(R.string.offline_download_failure)
offlineTitleView?.text =
context.resources.getString(R.string.offline_download_failure)
okView?.visibility = View.GONE
progressBar?.visibility = View.GONE
downloadPercentView?.visibility = View.GONE
@@ -193,7 +189,8 @@ class OfflineMapDialog(context: Context): BaseFloatDialog(context) {
rightView?.visibility = View.VISIBLE
vertLineView?.visibility = View.VISIBLE
rightView?.text = context.resources.getString(R.string.retry)
downloadResultImg?.background = ContextCompat.getDrawable(context, R.drawable.download_fail_icon)
downloadResultImg?.background =
ContextCompat.getDrawable(context, R.drawable.download_fail_icon)
}
}
}

View File

@@ -7,7 +7,6 @@ import android.content.ClipboardManager
import android.content.Context
import android.content.Intent
import android.graphics.Color
import android.net.*
import android.os.Build
import android.os.Process
import android.text.Html
@@ -18,8 +17,8 @@ import androidx.annotation.RequiresApi
import androidx.appcompat.widget.PopupMenu
import androidx.constraintlayout.widget.ConstraintLayout
import androidx.core.content.ContextCompat
import androidx.core.content.FileProvider
import androidx.core.view.*
import androidx.core.view.MenuCompat
import androidx.core.view.isVisible
import androidx.lifecycle.lifecycleScope
import chassis.Chassis
import com.mogo.cloud.passport.MoGoAiCloudClient
@@ -38,19 +37,19 @@ import com.mogo.eagle.core.data.deva.bizconfig.FuncBizConfig.Companion.BIZ_FULL_
import com.mogo.eagle.core.data.deva.bizconfig.FuncBizConfig.Companion.BIZ_RAIN_MODE
import com.mogo.eagle.core.data.deva.bizconfig.FuncBizConfig.Companion.BIZ_WARNING_UPLOAD
import com.mogo.eagle.core.data.deva.chain.ChainConstant
import com.mogo.eagle.core.data.deva.report.ReportEntity
import com.mogo.eagle.core.data.deva.scene.SceneModule
import com.mogo.eagle.core.data.enums.TrafficTypeEnum
import com.mogo.eagle.core.data.gnss.AccelerationEntity
import com.mogo.eagle.core.data.map.MogoLocation
import com.mogo.eagle.core.data.multidisplay.TelematicConstant
import com.mogo.eagle.core.data.obu.MogoObuConst
import com.mogo.eagle.core.data.obu.ObuStatusInfo
import com.mogo.eagle.core.data.deva.report.ReportEntity
import com.mogo.eagle.core.data.multidisplay.TelematicConstant
import com.mogo.eagle.core.function.api.autopilot.*
import com.mogo.eagle.core.function.api.devatools.IMoGoDevaToolsFuncConfigListener
import com.mogo.eagle.core.function.api.devatools.IMoGoDevaToolsListener
import com.mogo.eagle.core.function.api.datacenter.obu.IMoGoObuConnectListener
import com.mogo.eagle.core.function.api.datacenter.obu.IMoGoObuInfoListener
import com.mogo.eagle.core.function.api.devatools.IMoGoDevaToolsFuncConfigListener
import com.mogo.eagle.core.function.api.devatools.IMoGoDevaToolsListener
import com.mogo.eagle.core.function.api.setting.ISopSettingListener
import com.mogo.eagle.core.function.call.autopilot.*
import com.mogo.eagle.core.function.call.devatools.CallerDevaToolsFuncConfigListenerManager
@@ -66,7 +65,10 @@ import com.mogo.eagle.core.function.call.telematic.CallerTelematicManager
import com.mogo.eagle.core.function.hmi.R
import com.mogo.eagle.core.function.hmi.ui.logcatch.ILogViewListener
import com.mogo.eagle.core.function.hmi.ui.logcatch.LogInfoView
import com.mogo.eagle.core.utilcode.kotlin.*
import com.mogo.eagle.core.utilcode.kotlin.currentPadding
import com.mogo.eagle.core.utilcode.kotlin.lifecycleOwner
import com.mogo.eagle.core.utilcode.kotlin.onClick
import com.mogo.eagle.core.utilcode.kotlin.scope
import com.mogo.eagle.core.utilcode.mogo.AppIdentityModeUtils
import com.mogo.eagle.core.utilcode.mogo.logger.LogLevel
import com.mogo.eagle.core.utilcode.mogo.logger.Logger
@@ -75,11 +77,10 @@ import com.mogo.eagle.core.utilcode.mogo.permissions.BackgrounderPermission
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.*
import com.mogo.map.hdcache.IHdCacheListener
import com.mogo.map.MogoData.Companion.mogoMapData
import com.mogo.map.uicontroller.VisualAngleMode
import com.mogo.map.uicontroller.VisualAngleMode.*
import kotlinx.android.synthetic.main.view_debug_setting.view.*
import kotlinx.android.synthetic.main.view_debug_setting.view.tbRouteDynamicEffect
import kotlinx.coroutines.*
import mogo.telematics.pad.MessagePad
import mogo_msg.MogoReportMsg
@@ -194,10 +195,10 @@ internal class DebugSettingView @JvmOverloads constructor(
*/
private val timerTaskRefresh = object : TimerTask() {
override fun run() {
if(this@DebugSettingView == null){
if (this@DebugSettingView == null) {
return
}
if(!isRunCheck){
if (!isRunCheck) {
return
}
UiThreadHandler.post {
@@ -231,7 +232,7 @@ internal class DebugSettingView @JvmOverloads constructor(
//添加 底盘灯光数据 监听
CallerChassisLamplightListenerManager.addListener(TAG, this)
//雨天、美化、点云设置同步
CallerSopSettingManager.addListener(TAG,this)
CallerSopSettingManager.addListener(TAG, this)
//添加 业务配置监听
CallerDevaToolsFuncConfigListenerManager.registerDevaToolsFuncConfigListener(
@@ -299,11 +300,12 @@ internal class DebugSettingView @JvmOverloads constructor(
}
}
@SuppressLint("SetTextI18n")
private fun initView() {
post {
val maxHeight = ScreenUtils.getScreenHeight()-BarUtils.getStatusBarHeight()
val maxHeight = ScreenUtils.getScreenHeight() - BarUtils.getStatusBarHeight()
val height = clDebugContain.height
if(height>maxHeight){
if (height > maxHeight) {
val layoutParamsOther = clDebugContain.layoutParams
layoutParamsOther.height = maxHeight
clDebugContain.layoutParams = layoutParamsOther
@@ -593,12 +595,9 @@ internal class DebugSettingView @JvmOverloads constructor(
}
if (AppIdentityModeUtils.isPassenger(FunctionBuildConfig.appIdentityMode)) {
ThreadUtils.getIoPool().execute {
val isCached = CallerMapUIServiceManager.isCityDataCached()
isHDCached = isCached
UiThreadHandler.post {
btn_cache_hd_map.text = "缓存高精离线地图(${if (isCached) "已是最新版" else "待更新"}!)"
}
mogoMapData.get()?.isCityDataCached {
isHDCached = it
btn_cache_hd_map.text = "缓存高精离线地图(${if (it) "已是最新版" else "待更新"}!)"
}
btn_cache_hd_map.visibility = View.VISIBLE
}
@@ -633,9 +632,15 @@ internal class DebugSettingView @JvmOverloads constructor(
*/
tbControlPassengerDriverMonitor.setOnCheckedChangeListener { _, isChecked ->
if (isChecked) {
CallerTelematicManager.sendMsgToAllClients(TelematicConstant.CONTROL_PASSENGER_DRIVER_MONITOR, "1".toByteArray())
CallerTelematicManager.sendMsgToAllClients(
TelematicConstant.CONTROL_PASSENGER_DRIVER_MONITOR,
"1".toByteArray()
)
} else {
CallerTelematicManager.sendMsgToAllClients(TelematicConstant.CONTROL_PASSENGER_DRIVER_MONITOR, "0".toByteArray())
CallerTelematicManager.sendMsgToAllClients(
TelematicConstant.CONTROL_PASSENGER_DRIVER_MONITOR,
"0".toByteArray()
)
}
}
@@ -661,7 +666,8 @@ internal class DebugSettingView @JvmOverloads constructor(
// 初始化OBU IP信息
val ipAddress =
SharedPrefsMgr.getInstance(context).getString(MoGoConfig.OBU_IP, MogoObuConst.OBU_DEFAULT_IP)
SharedPrefsMgr.getInstance(context)
.getString(MoGoConfig.OBU_IP, MogoObuConst.OBU_DEFAULT_IP)
etObuIP.setText(ipAddress)
etObuIP.text?.let { etObuIP.setSelection(it.length) }
@@ -694,7 +700,7 @@ internal class DebugSettingView @JvmOverloads constructor(
tbIsDemoMode.isChecked = FunctionBuildConfig.isDemoMode
// 演示模式
tbIsDemoMode.setOnCheckedChangeListener { compoundButton, isChecked ->
if(!compoundButton.isPressed){
if (!compoundButton.isPressed) {
return@setOnCheckedChangeListener
}
FunctionBuildConfig.isDemoMode = !FunctionBuildConfig.isDemoMode
@@ -716,9 +722,11 @@ internal class DebugSettingView @JvmOverloads constructor(
}
tbIsStrictMode?.also {
it.isChecked = SharedPrefs.getInstance(Utils.getApp()).getBoolean("MOGO_STRICT_MODE_ENABLED", false)
it.isChecked = SharedPrefs.getInstance(Utils.getApp())
.getBoolean("MOGO_STRICT_MODE_ENABLED", false)
it.setOnCheckedChangeListener { _, isChecked ->
SharedPrefs.getInstance(Utils.getApp()).putBoolean("MOGO_STRICT_MODE_ENABLED", isChecked)
SharedPrefs.getInstance(Utils.getApp())
.putBoolean("MOGO_STRICT_MODE_ENABLED", isChecked)
scope.launch {
ToastUtils.showShort("配置生效, 2秒后重启应用...")
delay(2000)
@@ -731,7 +739,7 @@ internal class DebugSettingView @JvmOverloads constructor(
tbIsRainMode.isChecked = FunctionBuildConfig.isRainMode
//雨天模式
tbIsRainMode.setOnCheckedChangeListener { compoundButton, isChecked ->
if(!compoundButton.isPressed){
if (!compoundButton.isPressed) {
return@setOnCheckedChangeListener
}
CallerAutoPilotControlManager.setRainMode(isChecked)
@@ -848,16 +856,37 @@ internal class DebugSettingView @JvmOverloads constructor(
//TODO
tbIsDrawPath.setOnCheckedChangeListener { _, isChecked ->
ToastUtils.showShort("功能开发中")
}
if(FunctionBuildConfig.isDrawPointCloudData){
//如果点云效果是打开的,则自车光圈也跟随打开
tbCarAperture.isChecked = true
}else{
tbCarAperture.isChecked = FunctionBuildConfig.isDisplayAnimEnable
}
tbCarAperture.setOnCheckedChangeListener { compoundButton, isChecked ->
CallerMapUIServiceManager.getMapUIController()?.setDisplayAnimEnable(isChecked)
CallerSopSettingManager.invokeCarApertureListener(isChecked)
if(!compoundButton.isPressed){
return@setOnCheckedChangeListener
}
FunctionBuildConfig.isDisplayAnimEnable = isChecked
}
//初始化点云数据渲染情况
tbDrawPointCloudData.isChecked = FunctionBuildConfig.isDrawPointCloudData
//是否渲染点云数据
tbDrawPointCloudData.setOnCheckedChangeListener { compoundButton, isChecked ->
if(!compoundButton.isPressed){
if (!compoundButton.isPressed) {
return@setOnCheckedChangeListener
}
//打开点云效果时,如果自车光圈是关闭状态,则自动打开自车光圈(点云是跟随光圈的 默认没有光圈就不显示点云的)
if(isChecked && !FunctionBuildConfig.isDisplayAnimEnable){
tbCarAperture.isChecked = true
}else{
tbCarAperture.isChecked = FunctionBuildConfig.isDisplayAnimEnable
}
CallerAutoPilotControlManager.setIsDrawPointCloud(isChecked)
FunctionBuildConfig.isDrawPointCloudData = isChecked
CallerMapUIServiceManager.getMapUIController()?.setIsDrawPointCloud(isChecked)
@@ -872,7 +901,8 @@ internal class DebugSettingView @JvmOverloads constructor(
} else {
try {
val cloudSizeFloat = cloudSize.toFloat()
CallerMapUIServiceManager.getMapUIController()?.setPointCloudSize(cloudSizeFloat)
CallerMapUIServiceManager.getMapUIController()
?.setPointCloudSize(cloudSizeFloat)
} catch (e: Exception) {
ToastUtils.showShort("点云大小格式输入不正确")
}
@@ -918,7 +948,7 @@ internal class DebugSettingView @JvmOverloads constructor(
tbADASLog.isChecked = CallerAutoPilotControlManager.isEnableLog()
//如果工控机异常上报列表窗口为展示状态,则显示上报异常布局
if(CallerDevaToolsManager.getReportWindowStatus()){
if (CallerDevaToolsManager.getReportWindowStatus()) {
reportMsgLayout.visibility = View.VISIBLE
tbReportMore.isChecked = true
}
@@ -951,7 +981,7 @@ internal class DebugSettingView @JvmOverloads constructor(
clipboardManager?.setPrimaryClip(
ClipData.newPlainText(
"DockVersion",
CallerAutoPilotStatusListenerManager.getDockerVersion()?:""
CallerAutoPilotStatusListenerManager.getDockerVersion() ?: ""
)
)
ToastUtils.showLong("docker版本复制成功")
@@ -1041,7 +1071,7 @@ internal class DebugSettingView @JvmOverloads constructor(
//设置连接司机屏IP
btnConnectServerIp.setOnClickListener {
val ip = etConnectServerIp.text.toString()
if (!ip.isNullOrEmpty()) {
if (!ip.isEmpty()) {
CallerAutoPilotControlManager.connectSpecifiedServer(ip)
}
}
@@ -1064,13 +1094,15 @@ internal class DebugSettingView @JvmOverloads constructor(
}
if (!AppIdentityModeUtils.isTaxiDriver(FunctionBuildConfig.appIdentityMode)
&& !AppIdentityModeUtils.isBusDriver(FunctionBuildConfig.appIdentityMode)){
&& !AppIdentityModeUtils.isBusDriver(FunctionBuildConfig.appIdentityMode)
) {
tbStartAutopilotCommand.visibility = GONE
}
//切换环境
tvCurEnv.text = "当前环境:${CallerDevaToolsManager.getEnvCityName()}${CallerDevaToolsManager.getEnvNetMode()}"
tvCurEnv.text =
"当前环境:${CallerDevaToolsManager.getEnvCityName()}${CallerDevaToolsManager.getEnvNetMode()}"
btChangeEnv.onClick {
PopupMenu(context, btChangeEnv).also { p ->
p.menuInflater.inflate(R.menu.menu_env_pop, p.menu)
@@ -1086,13 +1118,22 @@ internal class DebugSettingView @JvmOverloads constructor(
R.id.env_reset ->
CallerDevaToolsManager.envConfigReset()
R.id.hy_product ->
CallerDevaToolsManager.envConfigChange("0734", DebugConfig.NET_MODE_RELEASE)
CallerDevaToolsManager.envConfigChange(
"0734",
DebugConfig.NET_MODE_RELEASE
)
R.id.hy_qa ->
CallerDevaToolsManager.envConfigChange("0734", DebugConfig.NET_MODE_QA)
R.id.hy_demo ->
CallerDevaToolsManager.envConfigChange("0734", DebugConfig.NET_MODE_DEMO)
CallerDevaToolsManager.envConfigChange(
"0734",
DebugConfig.NET_MODE_DEMO
)
R.id.bj_product ->
CallerDevaToolsManager.envConfigChange("010", DebugConfig.NET_MODE_RELEASE)
CallerDevaToolsManager.envConfigChange(
"010",
DebugConfig.NET_MODE_RELEASE
)
R.id.bj_qa ->
CallerDevaToolsManager.envConfigChange("010", DebugConfig.NET_MODE_QA)
R.id.bj_demo ->
@@ -1293,7 +1334,7 @@ internal class DebugSettingView @JvmOverloads constructor(
* 设置是否输出高精地图日志 true-打印日志false-不打印日志
*/
tbHdMapLog.setOnCheckedChangeListener { _, isChecked ->
CallerMapUIServiceManager.getMapUIController()?.setDebugMode(isChecked)
mogoMapData.get()?.setDebugMode(isChecked)
}
cbTraceLog.isChecked = CallerDevaToolsManager.getTraceLogStatus()
@@ -1575,8 +1616,10 @@ internal class DebugSettingView @JvmOverloads constructor(
/**
* 版本信息
*/
tvAppVersionName.text = "鹰眼版本:${AppUtils.getAppVersionName()} Git Hash${AppConfigInfo.workingBranchHash} \n渠道信息:${AppConfigInfo.flavor}"
tvAppVersionNameKey.text = "鹰眼版本:${AppUtils.getAppVersionName()} Git Hash${AppConfigInfo.workingBranchHash}\n渠道信息:${AppConfigInfo.flavor}"
tvAppVersionName.text =
"鹰眼版本:${AppUtils.getAppVersionName()} Git Hash${AppConfigInfo.workingBranchHash} \n渠道信息:${AppConfigInfo.flavor}"
tvAppVersionNameKey.text =
"鹰眼版本:${AppUtils.getAppVersionName()} Git Hash${AppConfigInfo.workingBranchHash}\n渠道信息:${AppConfigInfo.flavor}"
tvAutopilotProtocolVersionInfo.text =
"Autopilot协议版本${CallerAutoPilotControlManager.getProtocolVersion()}"
@@ -1593,9 +1636,12 @@ internal class DebugSettingView @JvmOverloads constructor(
tvGitBranchInfo.text = "Git分支${AppConfigInfo.workingBranchName}"
tvAppBuildTimeInfo.text = "版本构建时间:${AppConfigInfo.appBuildTime}"
if(tbBeautyMode.isVisible){
val version = ParseVersionUtils.parseVersion(true, CallerAutoPilotStatusListenerManager.getDockerVersion())
if(version >= 30100 && AppIdentityModeUtils.isTaxi(FunctionBuildConfig.appIdentityMode)){
if (tbBeautyMode.isVisible) {
val version = ParseVersionUtils.parseVersion(
true,
CallerAutoPilotStatusListenerManager.getDockerVersion()
)
if (version >= 30100 && AppIdentityModeUtils.isTaxi(FunctionBuildConfig.appIdentityMode)) {
tbBeautyMode.visibility = View.GONE
}
}
@@ -1628,7 +1674,7 @@ internal class DebugSettingView @JvmOverloads constructor(
"移动数据"
} else {
//WiFi
CommonUtils.getWifiName(context)?:""
CommonUtils.getWifiName(context) ?: ""
}
} else {
@@ -1703,11 +1749,14 @@ internal class DebugSettingView @JvmOverloads constructor(
tvIpcInfo.text = it
tvIpcInfoKey.text = it
}
tvCmdbCarInfoContent.text = SharedPrefsMgr.getInstance(context).getString(SharedPrefsConstants.CAR_INFO)?:""
tvCmdbCarInfoContent.text =
SharedPrefsMgr.getInstance(context).getString(SharedPrefsConstants.CAR_INFO) ?: ""
//APP升级功能
tvAppHost.text = "HOST地址" + SharedPrefsMgr.getInstance(context).getString(SharedPrefsConstants.HOST_ADDRESS)?:""
tvAppContent.text = "APP升级数据" + SharedPrefsMgr.getInstance(context).getString(SharedPrefsConstants.APP_UPGRADE_CONTENT)?:""
tvAppHost.text = "HOST地址" + SharedPrefsMgr.getInstance(context)
.getString(SharedPrefsConstants.HOST_ADDRESS) ?: ""
tvAppContent.text = "APP升级数据" + SharedPrefsMgr.getInstance(context)
.getString(SharedPrefsConstants.APP_UPGRADE_CONTENT) ?: ""
tvCarInfo.text =
"GPS时间${(mGnssInfo?.satelliteTime?.times(1000))?.toLong()}\n" +
@@ -1739,6 +1788,18 @@ internal class DebugSettingView @JvmOverloads constructor(
mTrajectoryInfoSize = 0
mRouteInfoSize = 0
if (FunctionBuildConfig.isDemoMode) {
tbIsDemoMode?.text = "关闭美化模式"
} else {
tbIsDemoMode?.text = "开启美化模式"
}
if (FunctionBuildConfig.isRainMode) {
tbIsRainMode?.text = "关闭雨天模式"
} else {
tbIsRainMode?.text = "开启雨天模式"
}
obuConnectStatusTv.text = Html.fromHtml(
"OBU连接状态${
if (AppConfigInfo.isConnectObu) {
@@ -2120,56 +2181,47 @@ internal class DebugSettingView @JvmOverloads constructor(
}
private fun restartApp() {
Utils.getApp().startActivity(Utils.getApp().packageManager.getLaunchIntentForPackage(Utils.getApp().packageName))
Utils.getApp()
.startActivity(Utils.getApp().packageManager.getLaunchIntentForPackage(Utils.getApp().packageName))
Process.killProcess(Process.myPid())
}
private fun cacheHDOfflineData(isGaoDe: Boolean) {
var progss = 0
if (isGaoDe) {// 拿到了高德地图的cityCode
CallerMapUIServiceManager.cacheHDDataByCity(object : IHdCacheListener {
override fun onMapHdCacheProgress(cityId: Int, progress: Double) {
// 更新进度
progss = progress.toInt()
if (progss == 100) {
isHDCached = true
btn_cache_hd_map.text = "缓存高精离线地图(已是最新版!)"
} else {
btn_cache_hd_map.text = "缓存高精离线地图(进度:${progss}%)"
}
}
override fun onMapHdCacheResult(cityId: Int, state: Int) {
if (state == 0) {// 失败
btn_cache_hd_map.text = "缓存高精离线地图(下载失败!)"
ToastUtils.showShort("下载失败,请重试!")
}
}
mogoMapData.get()?.cacheHDDataByCity({ _, progress ->
cacheHDCityProgressUpdate(progress)
}, { _, state ->
cacheHDCityResult(state)
})
} else {// 只拿到了高精的经纬度
mGnssInfo?.let { loc ->
CallerMapUIServiceManager.cacheHDDataByCityByLonLat(object : IHdCacheListener {
override fun onMapHdCacheProgress(cityId: Int, progress: Double) {
progss = progress.toInt()
if (progss == 100) {
isHDCached = true
btn_cache_hd_map.text = "缓存高精离线地图(已是最新版!)"
} else {
btn_cache_hd_map.text = "缓存高精离线地图(进度:${progss}%)"
}
}
override fun onMapHdCacheResult(cityId: Int, state: Int) {
if (state == 0) {// 失败
btn_cache_hd_map.text = "缓存高精离线地图(下载失败!)"
ToastUtils.showShort("下载失败,请重试!")
}
}
}, loc)
mogoMapData.get()?.cacheHDDataByCityByLonLat(loc, { _, progress ->
cacheHDCityProgressUpdate(progress)
}, { _, state ->
cacheHDCityResult(state)
})
}
}
}
private fun cacheHDCityProgressUpdate(progress: Double) {
// 更新进度
val progss = progress.toInt()
if (progss == 100) {
isHDCached = true
btn_cache_hd_map.text = "缓存高精离线地图(已是最新版!)"
} else {
btn_cache_hd_map.text = "缓存高精离线地图(进度:${progss}%)"
}
}
private fun cacheHDCityResult(state: Int) {
if (state == 0) {// 失败
btn_cache_hd_map.text = "缓存高精离线地图(下载失败!)"
ToastUtils.showShort("下载失败,请重试!")
}
}
override fun fwThreadClose() {
refreshTraceInfo()
}
@@ -2209,4 +2261,11 @@ internal class DebugSettingView @JvmOverloads constructor(
tbDrawPointCloudData.isChecked = status
}
/**
* 自车光圈
*/
override fun onCarApertureClickEvent(status: Boolean) {
tbCarAperture.isChecked = status
}
}

View File

@@ -390,6 +390,7 @@ internal class SOPSettingView @JvmOverloads constructor(
}
scCarAperture.setOnCheckedChangeListener { compoundButton, isChecked ->
CallerMapUIServiceManager.getMapUIController()?.setDisplayAnimEnable(isChecked)
CallerSopSettingManager.invokeCarApertureListener(isChecked)
hmiAction("SOP 是否展示自车光圈,",isChecked)
Log.i(TAG,"SOP 是否展示自车光圈,$isChecked")
if(!compoundButton.isPressed){
@@ -768,6 +769,10 @@ internal class SOPSettingView @JvmOverloads constructor(
scDrawPointCloudData.isChecked = status
}
override fun onCarApertureClickEvent(status: Boolean) {
scCarAperture.isChecked = status
}
/**
* 工控机配置参数获取
*/

View File

@@ -10,6 +10,7 @@ import com.mogo.eagle.core.data.autopilot.pnc.PncActionsHelper
import com.mogo.eagle.core.data.biz.trafficlight.TrafficLightResult
import com.mogo.eagle.core.data.biz.trafficlight.currentRoadTrafficLight
import com.mogo.eagle.core.data.biz.trafficlight.isRed
import com.mogo.eagle.core.data.biz.trafficlight.time
import com.mogo.eagle.core.data.deva.bizconfig.FuncBizConfig.Companion.BIZ_PNC_ACTIONS
import com.mogo.eagle.core.data.deva.bizconfig.FuncBizConfig.Companion.FOUNDATION
import com.mogo.eagle.core.function.api.autopilot.IMoGoAutopilotPlanningActionsListener
@@ -137,7 +138,7 @@ class PncActionsView @JvmOverloads constructor(
&& mTrafficLightResult!!.currentRoadTrafficLight() != null
&& mTrafficLightResult!!.currentRoadTrafficLight()!!.isRed()
) {
mTrafficLightResult!!.currentRoadTrafficLight()!!.remain.toString()
mTrafficLightResult!!.currentRoadTrafficLight()!!.time().toString()
} else {
""
}

View File

@@ -46,28 +46,26 @@ class SteeringBrakeView(context: Context, attrs: AttributeSet?) : ConstraintLayo
}
override fun onChassisLocationWGS84(gnssInfo: MogoLocation) {
if (gnssInfo != null) {
//设置刹车信息,小于默认认为是刹车
brakeLight =
if (gnssInfo.acceleration < SharedPrefsMgr.getInstance(Utils.getApp()).getFloat(
MoGoConfig.BRAKE_ACCELERATION_THRESHOLD, -2.5f
)
) {
1
} else {
0
}
CallerLogger.d(
"$M_HMI$TAG",
"---onAutopilotLightSwitchData ---Acceleration = " + gnssInfo.acceleration + "-- brakeLight = " + brakeLight
)
ThreadUtils.runOnUiThread {
if (!isShowTurnLight) { //在不展示转向灯的情况下,展示车辆刹车的动效
brakeView.visibility = View.VISIBLE
brakeView.setBrakeLight(brakeLight)
} else {
brakeView.visibility = View.GONE
}
//设置刹车信息,小于默认认为是刹车 //todo 优化sp获取不要每次回调都去调用sp
brakeLight =
if (gnssInfo.acceleration < SharedPrefsMgr.getInstance(Utils.getApp()).getFloat(
MoGoConfig.BRAKE_ACCELERATION_THRESHOLD, -2.5f
)
) {
1
} else {
0
}
CallerLogger.d(
"$M_HMI$TAG",
"---onAutopilotLightSwitchData ---Acceleration = " + gnssInfo.acceleration + "-- brakeLight = " + brakeLight
)
ThreadUtils.runOnUiThread {
if (!isShowTurnLight) { //在不展示转向灯的情况下,展示车辆刹车的动效
brakeView.visibility = View.VISIBLE
brakeView.setBrakeLight(brakeLight)
} else {
brakeView.visibility = View.GONE
}
}
}

View File

@@ -1,46 +0,0 @@
package com.mogo.eagle.core.function.hmi.ui.widget
import android.content.Context
import android.util.AttributeSet
import android.view.LayoutInflater
import android.view.View
import android.widget.FrameLayout
import com.mogo.eagle.core.function.call.map.CallerMapUIServiceManager.getMapUIController
import com.mogo.eagle.core.function.hmi.R
import com.mogo.map.uicontroller.VisualAngleMode
import kotlinx.android.synthetic.main.view_perspective_switch.view.*
/**
*@author xiaoyuzhou
*@date 2021/10/15 11:34 上午
* 视角切换按钮
*/
class PerspectiveSwitchView @JvmOverloads constructor(
context: Context,
attrs: AttributeSet? = null,
defStyleAttr: Int = 0
) : FrameLayout(context, attrs, defStyleAttr), View.OnClickListener{
override fun onAttachedToWindow() {
super.onAttachedToWindow()
LayoutInflater.from(context).inflate(R.layout.view_perspective_switch, this, true)
setBackgroundResource(R.drawable.module_switch_map_bg)
setOnClickListener(this)
}
override fun onClick(v: View?) {
getMapUIController()?.let {
if (it.currentMapVisualAngle.isLongSight) {
it.changeMapVisualAngle(VisualAngleMode.MODE_MEDIUM_SIGHT, null)
textSwitch.setText(R.string.module_map_model_normal)
} else if (it.currentMapVisualAngle.isMediumSight) {
it.changeMapVisualAngle(VisualAngleMode.MODE_LONG_SIGHT, null)
textSwitch.setText(R.string.module_map_model_faster)
} else {
it.changeMapVisualAngle(VisualAngleMode.MODE_LONG_SIGHT, null)
textSwitch.setText(R.string.module_map_model_faster)
}
}
}
}

View File

@@ -10,7 +10,9 @@ import com.mogo.eagle.core.function.api.map.roma.IMoGoRomaListener
import com.mogo.eagle.core.function.call.map.CallerMapIdentifyManager.romaTrigger
import com.mogo.eagle.core.function.call.map.CallerMapRomaListener
import com.mogo.eagle.core.function.hmi.R
import com.mogo.eagle.core.utilcode.util.*
import com.mogo.eagle.core.utilcode.util.ClickUtils
import com.mogo.eagle.core.utilcode.util.ThreadUtils
import com.mogo.eagle.core.utilcode.util.ToastUtils
import kotlinx.android.synthetic.main.view_roma_taxi_bg.view.ivRomaView
import kotlinx.android.synthetic.main.view_roma_taxi_bg.view.ll_roma_bg

View File

@@ -9,13 +9,11 @@ import androidx.constraintlayout.widget.ConstraintLayout
import com.mogo.eagle.core.data.app.AppConfigInfo
import com.mogo.eagle.core.data.deva.bindingcar.AdUpgradeStateHelper
import com.mogo.eagle.core.data.deva.bindingcar.IPCUpgradeStateInfo
import com.mogo.eagle.core.data.map.MogoLocation
import com.mogo.eagle.core.function.api.autopilot.IMoGoAutopilotStatusListener
import com.mogo.eagle.core.function.api.autopilot.IMoGoChassisLocationWGS84Listener
import com.mogo.eagle.core.function.api.devatools.IMoGoDevaToolsListener
import com.mogo.eagle.core.function.api.hmi.autopilot.IMoGoCheckAutoPilotBtnListener
import com.mogo.eagle.core.function.call.autopilot.CallerAutoPilotStatusListenerManager
import com.mogo.eagle.core.function.call.autopilot.CallerChassisLocationWGS84ListenerManager
import com.mogo.eagle.core.function.call.autopilot.CallerChassisLocationWGS84ListenerManager.getChassisLocationWGS84
import com.mogo.eagle.core.function.call.devatools.CallerDevaToolsListenerManager
import com.mogo.eagle.core.function.call.devatools.CallerDevaToolsManager
import com.mogo.eagle.core.function.call.hmi.CallerHmiListenerManager
@@ -26,6 +24,7 @@ import com.mogo.eagle.core.function.hmi.ui.utils.HmiActionLog.Companion.hmiActio
import com.mogo.eagle.core.utilcode.mogo.logger.CallerLogger
import com.mogo.eagle.core.utilcode.mogo.logger.scene.SceneConstant.Companion.M_HMI
import com.mogo.eagle.core.utilcode.util.*
import com.mogo.map.MogoData.Companion.mogoMapData
import kotlinx.android.synthetic.main.view_system_version.view.*
import system_master.SsmInfo
import system_master.SystemStatusInfo
@@ -41,7 +40,7 @@ class SystemVersionView @JvmOverloads constructor(
attrs: AttributeSet? = null,
defStyleAttr: Int = 0
) : ConstraintLayout(context, attrs, defStyleAttr), IMoGoAutopilotStatusListener,
IMoGoDevaToolsListener, IMoGoCheckAutoPilotBtnListener, IMoGoChassisLocationWGS84Listener {
IMoGoDevaToolsListener, IMoGoCheckAutoPilotBtnListener {
companion object {
const val TAG = "SystemVersionView"
@@ -56,7 +55,6 @@ class SystemVersionView @JvmOverloads constructor(
private var currentProgress: Int = -1 //当前已下载包体大小
private var isHDCached = false
private var location: MogoLocation? = null
init {
LayoutInflater.from(context).inflate(R.layout.view_system_version, this, true)
@@ -140,17 +138,17 @@ class SystemVersionView @JvmOverloads constructor(
ivHDCache.setOnClickListener {
hmiAction(
"$M_HMI$TAG",
"HD map view click , isHDCached:$isHDCached , lon:${location?.longitude} , lat:${location?.latitude}"
"HD map view click , isHDCached:$isHDCached , lon:${getChassisLocationWGS84().longitude} , lat:${getChassisLocationWGS84().latitude}"
)
if (isHDCached) {// 已缓存
ToastUtils.showShort(resources.getString(R.string.offline_had_downloaded))
} else {// 未缓存
if (CallerMapUIServiceManager.getCityCode().isNullOrEmpty()) {// 未拿到高德的cityCode
if (location == null || (location!!.longitude <= 0.0 && location!!.latitude <= 0.0)) {// 未拿到高精的经纬度
if ((getChassisLocationWGS84().longitude <= 0.0 && getChassisLocationWGS84().latitude <= 0.0)) {// 未拿到高精的经纬度
ToastUtils.showShort(resources.getString(R.string.location_try_again))
} else {// 拿到了高精的经纬度
val dialog = OfflineMapDialog(context)
dialog.location = location
dialog.location = getChassisLocationWGS84()
dialog.show()
}
} else {// 拿到高德的cityCode
@@ -159,11 +157,8 @@ class SystemVersionView @JvmOverloads constructor(
}
}
ThreadUtils.getIoPool().execute {
val isCached = CallerMapUIServiceManager.isCityDataCached()
UiThreadHandler.post {
updateHDDataCacheStatus(isCached)
}
mogoMapData.get()?.isCityDataCached {
updateHDDataCacheStatus(it)
}
if (AdUpgradeStateHelper.isConfirmUpgrade()) {
@@ -311,7 +306,6 @@ class SystemVersionView @JvmOverloads constructor(
CallerHmiListenerManager.addListener(TAG, this)
CallerAutoPilotStatusListenerManager.addListener(TAG, this)
CallerDevaToolsListenerManager.addListener(TAG, this)
CallerChassisLocationWGS84ListenerManager.addListener(TAG, this)
needQueryContainers = true
}
@@ -323,7 +317,6 @@ class SystemVersionView @JvmOverloads constructor(
CallerHmiListenerManager.removeListener(TAG)
CallerAutoPilotStatusListenerManager.removeListener(TAG)
CallerDevaToolsListenerManager.removeListener(TAG)
CallerChassisLocationWGS84ListenerManager.removeListener(TAG)
needQueryContainers = false
}
@@ -366,22 +359,18 @@ class SystemVersionView @JvmOverloads constructor(
adCircularProgressView?.visibility = View.GONE
}
override fun onChassisLocationWGS84(gnssInfo: MogoLocation) {
location = gnssInfo
}
/**
* 状态查询应答
* @param status 数据
* HQ、M1 MAP350开始弃用其他车型MAP360开始弃用
*/
override fun onAutopilotStatusRespByQuery(status: SystemStatusInfo.StatusInfo) {
Log.i(TAG,"hdMapVer="+status.hdMapVer)
Log.i(TAG, "hdMapVer=" + status.hdMapVer)
//hdMapVer返回示例/home/mogo/autopilot/share/hadmap_engine/data/hadmap_data/db.sqlite|bj|2.2.7|对bus路线上的junction进行修改对原609场景修改为6091、6092、6201、 6202四种细分场景并对通往园区路口改为619
if(status.hdMapVer!= null && status.hdMapVer.isNotEmpty()){
if (status.hdMapVer != null && status.hdMapVer.isNotEmpty()) {
//对地图版本进行截取
val city = status.hdMapVer.substringAfter(".sqlite|").substringBefore("|")
val version =status.hdMapVer.substringAfter("$city|").substringBefore("|")
val version = status.hdMapVer.substringAfter("$city|").substringBefore("|")
AppConfigInfo.adHdMapVersion = "${city}_${version}"
updateAdHdMapVersion()
}
@@ -395,12 +384,12 @@ class SystemVersionView @JvmOverloads constructor(
* @param statusInf 数据
*/
override fun onSystemStatus(statusInf: SsmInfo.SsmStatusInf) {
Log.i(TAG,"hdMapVer="+statusInf.hdMapVer)
Log.i(TAG, "hdMapVer=" + statusInf.hdMapVer)
//hdMapVer返回示例/home/mogo/autopilot/share/hadmap_engine/data/hadmap_data/db.sqlite|bj|2.2.7|对bus路线上的junction进行修改对原609场景修改为6091、6092、6201、 6202四种细分场景并对通往园区路口改为619
if(statusInf.hdMapVer!= null && statusInf.hdMapVer.isNotEmpty()){
if (statusInf.hdMapVer != null && statusInf.hdMapVer.isNotEmpty()) {
//对地图版本进行截取
val city = statusInf.hdMapVer.substringAfter(".sqlite|").substringBefore("|")
val version =statusInf.hdMapVer.substringAfter("$city|").substringBefore("|")
val version = statusInf.hdMapVer.substringAfter("$city|").substringBefore("|")
AppConfigInfo.adHdMapVersion = "${city}_${version}"
updateAdHdMapVersion()
}
@@ -409,8 +398,8 @@ class SystemVersionView @JvmOverloads constructor(
/**
* 更新工控机高精地图版本
*/
private fun updateAdHdMapVersion(){
if(tvAdHdMapVersionContent.text.isNullOrEmpty() && AppConfigInfo.adHdMapVersion.isNotEmpty() || tvAdHdMapVersionContent.text != AppConfigInfo.adHdMapVersion){
private fun updateAdHdMapVersion() {
if (tvAdHdMapVersionContent.text.isNullOrEmpty() && AppConfigInfo.adHdMapVersion.isNotEmpty() || tvAdHdMapVersionContent.text != AppConfigInfo.adHdMapVersion) {
ThreadUtils.runOnUiThread {
tvAdHdMapVersionContent.text = AppConfigInfo.adHdMapVersion
}

View File

@@ -1,15 +1,12 @@
package com.mogo.eagle.core.function.main
import android.Manifest
import android.content.Intent
import android.content.pm.PackageManager
import android.net.Uri
import android.os.Build
import android.os.Bundle
import android.provider.Settings
import android.view.*
import android.widget.FrameLayout
import androidx.core.app.ActivityCompat
import androidx.recyclerview.widget.LinearLayoutManager
import com.kwai.koom.base.MonitorManager.addMonitorConfig
import com.kwai.koom.javaoom.monitor.OOMHprofUploader
@@ -89,14 +86,12 @@ open class MainActivity : MvpActivity<MainView?, MainPresenter?>(), MainView,
initConnectInfoRV()
CallerHmiManager.init(this)
//申请悬浮窗权限
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
// 检查是否有悬浮窗权限
if (Settings.canDrawOverlays(this)) {
return
}
PermissionsDialogUtils.openAppDetails(this, "显示悬浮窗", REQUEST_CODE_DIALOG)
// 检查是否有悬浮窗权限
if (Settings.canDrawOverlays(this)) {
return
}
//申请悬浮窗权限
PermissionsDialogUtils.openAppDetails(this, "显示悬浮窗", REQUEST_CODE_DIALOG)
}
private fun injectStatusBar() {
@@ -121,7 +116,6 @@ open class MainActivity : MvpActivity<MainView?, MainPresenter?>(), MainView,
decorView.addView(statusBarView, statusBarLP)
}
// todo 优化 车聊聊
private fun injectFloatView() {
val decorView = this.window.decorView as? FrameLayout ?: return

View File

@@ -14,7 +14,6 @@ import android.os.Handler;
import android.os.Process;
import android.text.TextUtils;
import android.util.Log;
import android.view.KeyEvent;
import androidx.annotation.Nullable;
@@ -23,14 +22,11 @@ import com.mogo.commons.module.intent.IMogoIntentListener;
import com.mogo.commons.module.intent.IntentManager;
import com.mogo.eagle.core.function.api.base.IMoGoFunctionProvider;
import com.mogo.eagle.core.function.api.setting.IMoGoSkinModeChangeListener;
import com.mogo.eagle.core.function.call.autopilot.CallerAutoPilotControlManager;
import com.mogo.eagle.core.function.call.autopilot.CallerAutoPilotStatusListenerManager;
import com.mogo.eagle.core.function.call.setting.CallerSkinModeListenerManager;
import com.mogo.eagle.core.function.hmi.R;
import com.mogo.eagle.core.function.main.moujie.BluetoothMonitorReceiver;
import com.mogo.eagle.core.utilcode.mogo.logger.CallerLogger;
import com.mogo.eagle.core.utilcode.mogo.storage.SharedPrefsMgr;
import com.mogo.eagle.core.utilcode.util.ToastUtils;
import com.rousetime.android_startup.model.CostTimesModel;
import com.zhjt.service.chain.ChainLog;
@@ -40,8 +36,6 @@ import org.greenrobot.eventbus.Subscribe;
import java.lang.reflect.Method;
import java.util.List;
import java.util.Set;
import java.util.Timer;
import java.util.TimerTask;
/**
* 针对作为Launcher的情况做个性化操作 TODO 测试用的,可删除
@@ -54,10 +48,6 @@ public class PassengerLauncherActivity extends MainActivity implements IMogoInte
private final static Handler handlerV2XEvent = new Handler();
private static Runnable runnableV2XEvent;
private volatile double accelerated;//加速度
private Timer timerHorn;
private Timer timerAcc;
private BluetoothMonitorReceiver mBluetoothReceiver = null;
private BluetoothAdapter mBluetoothAdapter;

View File

@@ -1775,6 +1775,22 @@
app:layout_constraintRight_toRightOf="@id/tbIsDrawAutopilotTrajectoryData"
app:layout_constraintTop_toBottomOf="@id/tbIsDrawAutopilotTrajectoryData" />
<ToggleButton
android:id="@+id/tbCarAperture"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_margin="2dp"
android:padding="@dimen/dp_20"
android:textColor="#000"
android:textOff="开启自车光圈"
android:textOn="关闭自车光圈"
android:textSize="@dimen/dp_24"
app:layout_constraintLeft_toRightOf="@id/tbChangeAutoPilotStatus"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toBottomOf="@id/tbIsDrawAutopilotTrajectoryData"
/>
<ToggleButton
android:id="@+id/tbDrawPointCloudData"
android:layout_width="0dp"
@@ -1785,9 +1801,10 @@
android:textOff="开启渲染点云数据"
android:textOn="关闭渲染点云数据"
android:textSize="@dimen/dp_24"
app:layout_constraintLeft_toRightOf="@id/tbChangeAutoPilotStatus"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toBottomOf="@id/tbIsDrawAutopilotTrajectoryData" />
app:layout_constraintLeft_toLeftOf="@id/tbChangeAutoPilotStatus"
app:layout_constraintRight_toRightOf="@id/tbChangeAutoPilotStatus"
app:layout_constraintTop_toBottomOf="@id/tbChangeAutoPilotStatus"
/>
<Button
android:id="@+id/btnPointCloudSize"

View File

@@ -1,31 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/module_switch_model_layout"
android:layout_width="@dimen/module_switch_map"
android:layout_height="@dimen/module_switch_map_height">
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:gravity="center"
android:orientation="horizontal">
<ImageView
android:id="@+id/iconSwitch"
android:layout_width="@dimen/module_switch_image"
android:layout_height="@dimen/module_switch_image"
android:layout_gravity="left|center_vertical"
android:paddingLeft="@dimen/module_switch_margin_left"
android:src="@drawable/module_switch_map_angle" />
<TextView
android:id="@+id/textSwitch"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:paddingLeft="@dimen/module_switch_margin_left"
android:text="@string/module_map_model_normal"
android:textColor="@color/color_white"
android:textSize="@dimen/module_switch_text_size" />
</LinearLayout>
</FrameLayout>