[2.15.0_merge_3.2.0]
This commit is contained in:
@@ -92,6 +92,22 @@ object DataManager {
|
||||
}
|
||||
}
|
||||
|
||||
fun delMsgTable(context: Context) {
|
||||
if (Thread.currentThread() == Looper.getMainLooper().thread) {
|
||||
scope.launch {
|
||||
withContext(Dispatchers.Default) {
|
||||
MsgBoxDb.getDb(context)
|
||||
.monitorDao()
|
||||
.deleteMsgTable()
|
||||
}
|
||||
}
|
||||
} else {
|
||||
MsgBoxDb.getDb(context)
|
||||
.monitorDao()
|
||||
.deleteMsgTable()
|
||||
}
|
||||
}
|
||||
|
||||
private fun realSaveMsg(msg: MsgBoxBean) {
|
||||
val type = msg.type
|
||||
msg.timestamp = System.currentTimeMillis()
|
||||
|
||||
@@ -34,6 +34,10 @@ class MsgBoxProvider : IMsgBoxProvider {
|
||||
DataManager.saveMsg(bean)
|
||||
}
|
||||
|
||||
override fun delMsgTable(context: Context) {
|
||||
DataManager.delMsgTable(context)
|
||||
}
|
||||
|
||||
override fun getCachedNotifyData(): List<MsgBoxBean> {
|
||||
return DataManager.getNotifyData()
|
||||
}
|
||||
|
||||
@@ -15,4 +15,7 @@ interface MsgBoxDao {
|
||||
|
||||
@Query("SELECT * FROM t_msg_box")
|
||||
fun getAllCachedMessages(): List<MsgBoxInfo>
|
||||
|
||||
@Query("DELETE FROM t_msg_box")
|
||||
fun deleteMsgTable()
|
||||
}
|
||||
@@ -89,6 +89,11 @@ dependencies {
|
||||
implementation rootProject.ext.dependencies.androidautoSize
|
||||
implementation rootProject.ext.dependencies.koomnative
|
||||
implementation rootProject.ext.dependencies.koomxhook
|
||||
implementation group: "com.tencent.matrix", name: "matrix-android-lib", version: MATRIX_VERSION, changing: true
|
||||
implementation group: "com.tencent.matrix", name: "matrix-android-commons", version: MATRIX_VERSION, changing: true
|
||||
implementation group: "com.tencent.matrix", name: "matrix-trace-canary", version: MATRIX_VERSION, changing: true
|
||||
implementation group: "com.tencent.matrix", name: "matrix-io-canary", version: MATRIX_VERSION, changing: true
|
||||
implementation group: "com.tencent.matrix", name: "matrix-hooks", version: MATRIX_VERSION, changing: true
|
||||
|
||||
implementation project(':foudations:mogo-commons')
|
||||
implementation project(':core:mogo-core-utils')
|
||||
|
||||
@@ -9,8 +9,9 @@ import com.alibaba.android.arouter.facade.annotation.Route
|
||||
import com.mogo.commons.AbsMogoApplication
|
||||
import com.mogo.commons.debug.DebugConfig
|
||||
import com.mogo.eagle.core.data.EnvConfig
|
||||
import com.mogo.eagle.core.data.deva.bindingcar.ModifyBindingcarInfo
|
||||
import com.mogo.eagle.core.data.constants.MogoServicePaths
|
||||
import com.mogo.eagle.core.data.deva.bindingcar.ModifyBindingcarInfo
|
||||
import com.mogo.eagle.core.data.deva.chain.ChainConstant
|
||||
import com.mogo.eagle.core.data.deva.chain.ChainLogParam
|
||||
import com.mogo.eagle.core.data.deva.scene.SceneModule
|
||||
import com.mogo.eagle.core.data.deva.scene.SceneTAG
|
||||
@@ -21,6 +22,16 @@ import com.mogo.eagle.core.function.api.devatools.strict.*
|
||||
import com.mogo.eagle.core.function.call.map.*
|
||||
import com.mogo.eagle.core.function.api.devatools.download.*
|
||||
import com.mogo.eagle.core.utilcode.mogo.logger.CallerLogger
|
||||
import com.mogo.eagle.core.utilcode.mogo.logger.CallerLogger.w
|
||||
import com.tencent.matrix.Matrix
|
||||
import com.tencent.matrix.iocanary.IOCanaryPlugin
|
||||
import com.tencent.matrix.iocanary.config.IOConfig
|
||||
import com.tencent.matrix.plugin.Plugin
|
||||
import com.tencent.matrix.plugin.PluginListener
|
||||
import com.tencent.matrix.report.Issue
|
||||
import com.tencent.matrix.trace.TracePlugin
|
||||
import com.tencent.matrix.trace.config.SharePluginInfo
|
||||
import com.tencent.matrix.trace.config.TraceConfig
|
||||
import com.zhjt.mogo_core_function_devatools.apm.*
|
||||
import com.mogo.eagle.core.function.api.upgrade.*
|
||||
import com.zhjt.mogo_core_function_devatools.badcase.BadCaseManager
|
||||
@@ -31,11 +42,11 @@ import com.zhjt.mogo_core_function_devatools.funcconfig.FuncConfigCenter.Compani
|
||||
import com.zhjt.mogo_core_function_devatools.funcconfig.FuncConfigImpl
|
||||
import com.zhjt.mogo_core_function_devatools.koom.KoomInitTask
|
||||
import com.zhjt.mogo_core_function_devatools.logcatch.MogoLogCatchManager
|
||||
import com.zhjt.mogo_core_function_devatools.matrix.DynamicConfigImpl
|
||||
import com.zhjt.mogo_core_function_devatools.mofang.MoFangManager.Companion.moFangManager
|
||||
import com.zhjt.mogo_core_function_devatools.monitor.MonitorManager
|
||||
import com.zhjt.mogo_core_function_devatools.monitor.db.MonitorDb
|
||||
import com.zhjt.mogo_core_function_devatools.monitor.db.MonitorDb.Companion.getDb
|
||||
import com.zhjt.mogo_core_function_devatools.report.IPCReportManager
|
||||
import com.zhjt.mogo_core_function_devatools.report.IPCReportManager.Companion.iPCReportManager
|
||||
import com.zhjt.mogo_core_function_devatools.scene.SceneManager.Companion.sceneManager
|
||||
import com.zhjt.mogo_core_function_devatools.status.StatusManager
|
||||
@@ -43,6 +54,8 @@ import com.zhjt.mogo_core_function_devatools.strict.*
|
||||
import com.zhjt.mogo_core_function_devatools.trace.TraceManager.Companion.traceManager
|
||||
import com.zhjt.mogo_core_function_devatools.tts.TtsManager.Companion.ttsManager
|
||||
import com.zhjt.mogo_core_function_devatools.upgrade.UpgradeManager.Companion.upgradeManager
|
||||
import com.zhjt.service.chain.ChainLog
|
||||
import com.zhjt.service.chain.TracingConstants.Endpoint.Companion.PAD
|
||||
|
||||
@Route(path = MogoServicePaths.PATH_DEVA_TOOLS)
|
||||
class DevaToolsProvider : IDevaToolsProvider {
|
||||
@@ -65,12 +78,13 @@ class DevaToolsProvider : IDevaToolsProvider {
|
||||
}
|
||||
|
||||
override fun initBiz() {
|
||||
if (DebugConfig.isDebug()) {
|
||||
KoomInitTask.init(AbsMogoApplication.getApp())
|
||||
}
|
||||
ttsManager.initTts(mContext!!) //todo
|
||||
//链路相关
|
||||
traceManager.init(mContext!!)
|
||||
if (DebugConfig.isDebug()) {
|
||||
KoomInitTask.init(AbsMogoApplication.getApp())
|
||||
initMatrix()
|
||||
}
|
||||
ttsManager.initTts(mContext!!) //todo
|
||||
bizConfigCenter.init(mContext!!)
|
||||
FuncConfigImpl.init()
|
||||
MogoLogCatchManager.init(mContext!!)
|
||||
@@ -107,6 +121,76 @@ class DevaToolsProvider : IDevaToolsProvider {
|
||||
}
|
||||
}
|
||||
|
||||
private fun initMatrix() {
|
||||
val builder: Matrix.Builder = Matrix.Builder(AbsMogoApplication.getApp())
|
||||
builder.pluginListener(object : PluginListener {
|
||||
override fun onInit(plugin: Plugin?) {
|
||||
}
|
||||
|
||||
override fun onStart(plugin: Plugin?) {
|
||||
}
|
||||
|
||||
override fun onStop(plugin: Plugin?) {
|
||||
}
|
||||
|
||||
override fun onDestroy(plugin: Plugin?) {
|
||||
}
|
||||
|
||||
override fun onReportIssue(issue: Issue?) {
|
||||
var isEvil = false
|
||||
issue?.apply {
|
||||
if (plugin is TracePlugin) {
|
||||
if (tag == SharePluginInfo.TAG_PLUGIN_EVIL_METHOD) {
|
||||
isEvil = true
|
||||
printEvilMsg(issue.toString())
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!isEvil) {
|
||||
w("TraceCanary", issue?.toString())
|
||||
}
|
||||
}
|
||||
})
|
||||
val config: TraceConfig = TraceConfig.Builder()
|
||||
.enableFPS(true) // 帧率
|
||||
.enableEvilMethodTrace(true) // 慢方法
|
||||
.enableAnrTrace(true) // anr
|
||||
.enableStartup(true) // app启动
|
||||
.isDebug(true) // debug包
|
||||
.isDevEnv(true) // dev环境
|
||||
.build()
|
||||
|
||||
// Trace Canary插件
|
||||
val tracePlugin = TracePlugin(config)
|
||||
builder.plugin(tracePlugin)
|
||||
|
||||
val ioCanaryPlugin = IOCanaryPlugin(
|
||||
IOConfig.Builder()
|
||||
.dynamicConfig(DynamicConfigImpl())
|
||||
.build())
|
||||
|
||||
builder.plugin(ioCanaryPlugin)
|
||||
|
||||
Matrix.init(builder.build())
|
||||
// 日志刷太快,关掉
|
||||
Matrix.setLogIml(null)
|
||||
// 开启Trace Canary
|
||||
tracePlugin.start()
|
||||
ioCanaryPlugin.start()
|
||||
}
|
||||
|
||||
@ChainLog(
|
||||
linkChainLog = ChainConstant.CHAIN_LINK_LOG_ANR,
|
||||
linkCode = ChainConstant.CHAIN_LINK_ANR,
|
||||
endpoint = PAD,
|
||||
nodeAliasCode = ChainConstant.CHAIN_ALIAS_CODE_RECORD_ANR,
|
||||
paramIndexes = [0],
|
||||
clientPkFileName = "sn"
|
||||
)
|
||||
private fun printEvilMsg(evilMethod: String) {
|
||||
w("TraceCanary", evilMethod)
|
||||
}
|
||||
|
||||
override fun startLogCatch() {
|
||||
MogoLogCatchManager.startCatchLog()
|
||||
}
|
||||
|
||||
@@ -0,0 +1,43 @@
|
||||
package com.zhjt.mogo_core_function_devatools.matrix
|
||||
|
||||
import com.tencent.mrs.plugin.IDynamicConfig
|
||||
|
||||
class DynamicConfigImpl: IDynamicConfig {
|
||||
|
||||
fun isFPSEnable(): Boolean {
|
||||
return true
|
||||
}
|
||||
|
||||
fun isTraceEnable(): Boolean {
|
||||
return true
|
||||
}
|
||||
|
||||
fun isMatrixEnable(): Boolean {
|
||||
return true
|
||||
}
|
||||
|
||||
fun isDumpHprof(): Boolean {
|
||||
return false
|
||||
}
|
||||
|
||||
override fun get(key: String?, defStr: String?): String {
|
||||
return ""
|
||||
}
|
||||
|
||||
override fun get(key: String?, defInt: Int): Int {
|
||||
return 0
|
||||
}
|
||||
|
||||
override fun get(key: String?, defLong: Long): Long {
|
||||
return 0L
|
||||
}
|
||||
|
||||
override fun get(key: String?, defBool: Boolean): Boolean {
|
||||
return false
|
||||
}
|
||||
|
||||
override fun get(key: String?, defFloat: Float): Float {
|
||||
return 0f
|
||||
}
|
||||
|
||||
}
|
||||
@@ -67,6 +67,8 @@ class TraceManager : IMoGoCloudListener, IMoGoAutopilotCarConfigListener {
|
||||
FwBuild(true, -1, pkgName + ChainConstant.CHAIN_LINK_LOG_ADAS_PLANNING_ACTIONS)
|
||||
fwBuildMap[ChainConstant.CHAIN_LINK_LOG_NATIVE_LEAK] =
|
||||
FwBuild(true, -1, pkgName + ChainConstant.CHAIN_LINK_LOG_RECORD_NATIVE_LEAK)
|
||||
fwBuildMap[ChainConstant.CHAIN_LINK_LOG_ANR] =
|
||||
FwBuild(true, -1, pkgName + ChainConstant.CHAIN_LINK_LOG_RECORD_ANR)
|
||||
fwBuildMap[ChainConstant.CHAIN_LINK_LOG_CLOUD_V2N] =
|
||||
FwBuild(true, -1, pkgName + ChainConstant.CHAIN_LINK_LOG_CLOUD_WEB_SOCKET_V2N)
|
||||
fwBuildMap[ChainConstant.CHAIN_LINK_LOG_HD_MAP] =
|
||||
@@ -93,6 +95,8 @@ class TraceManager : IMoGoCloudListener, IMoGoAutopilotCarConfigListener {
|
||||
ChainLogParam(true, "ADAS PLANNING 决策行为")
|
||||
traceInfoCache[ChainConstant.CHAIN_LINK_LOG_NATIVE_LEAK] =
|
||||
ChainLogParam(true, "Native Leak Record")
|
||||
traceInfoCache[ChainConstant.CHAIN_LINK_LOG_ANR] =
|
||||
ChainLogParam(true, "ANR Record")
|
||||
traceInfoCache[ChainConstant.CHAIN_LINK_LOG_CLOUD_V2N] =
|
||||
ChainLogParam(true, "Cloud WebSocket V2N")
|
||||
traceInfoCache[ChainConstant.CHAIN_LINK_LOG_HD_MAP] =
|
||||
|
||||
@@ -47,7 +47,8 @@ class BusOperationView @JvmOverloads constructor(
|
||||
ivGotoPersonalInfo.visibility = GONE
|
||||
}
|
||||
|
||||
if (AppIdentityModeUtils.isShuttle(FunctionBuildConfig.appIdentityMode)) {
|
||||
if (AppIdentityModeUtils.isShuttle(FunctionBuildConfig.appIdentityMode) ||
|
||||
AppIdentityModeUtils.isCharter(FunctionBuildConfig.appIdentityMode)) {
|
||||
actvAccountQR.visibility = VISIBLE
|
||||
}else{
|
||||
actvAccountQR.visibility = GONE
|
||||
|
||||
@@ -15,6 +15,7 @@
|
||||
<dimen name="dp_18">18dp</dimen>
|
||||
<dimen name="dp_30">30dp</dimen>
|
||||
<dimen name="dp_34">34dp</dimen>
|
||||
<dimen name="dp_34_5">34.5dp</dimen>
|
||||
<dimen name="dp_36">36dp</dimen>
|
||||
<dimen name="dp_38">38dp</dimen>
|
||||
<dimen name="dp_42">42dp</dimen>
|
||||
|
||||
@@ -107,6 +107,8 @@ class OverMapView @JvmOverloads constructor(
|
||||
private var mBottomPolyline: Polyline? = null
|
||||
private var mCoveredPolyline: Polyline? = null
|
||||
|
||||
private var mSitePolyline: Polyline? = null
|
||||
|
||||
// 计算索引并设置对应的Bitmap
|
||||
var arrivedBitmap: BitmapDescriptor? = null
|
||||
var unArrivedBitmap: BitmapDescriptor? = null
|
||||
@@ -120,6 +122,7 @@ class OverMapView @JvmOverloads constructor(
|
||||
var mCustomMapStyleOptions: CustomMapStyleOptions? = null
|
||||
var currMarkerList: ArrayList<Marker>? = null
|
||||
var siteMarkerList: ArrayList<Marker>? = null
|
||||
var siteNameList: ArrayList<Marker>? = null
|
||||
|
||||
companion object {
|
||||
const val TAG = "OverMapView"
|
||||
@@ -226,7 +229,7 @@ class OverMapView @JvmOverloads constructor(
|
||||
|
||||
@MainThread
|
||||
fun drawSiteMarkers(
|
||||
siteMarkers: List<SiteMarkerBean>?,
|
||||
siteMarkers: List<SiteMarkerBean>?
|
||||
) {
|
||||
if (siteMarkers.isNullOrEmpty()) return
|
||||
clearSiteMarkers()
|
||||
@@ -253,6 +256,64 @@ class OverMapView @JvmOverloads constructor(
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 绘制站点名
|
||||
*/
|
||||
fun drawSiteNameViews(siteMarkers: List<SiteMarkerBean>?) {
|
||||
if (siteMarkers.isNullOrEmpty()) return
|
||||
clearSiteMarkers()
|
||||
val markerOptionsList = ArrayList<MarkerOptions>()
|
||||
for (siteMarkerBean in siteMarkers) {
|
||||
val markerOption = MarkerOptions()
|
||||
markerOption.position(siteMarkerBean.latLng)
|
||||
markerOption.anchor(siteMarkerBean.anchorX, siteMarkerBean.anchorY)
|
||||
markerOption.icon(
|
||||
BitmapDescriptorFactory.fromBitmap(siteMarkerBean.bitmap)
|
||||
)
|
||||
markerOptionsList.add(markerOption)
|
||||
}
|
||||
siteNameList = mAMap!!.addMarkers(markerOptionsList, false)
|
||||
}
|
||||
|
||||
/**
|
||||
* 更新站点信息Bitmap展示
|
||||
*/
|
||||
fun updateSiteNameView(index: Int, bitmap: Bitmap) {
|
||||
if (siteNameList != null && index in 0 until siteNameList!!.size) {
|
||||
val siteNameMarker = siteNameList!![index]
|
||||
siteNameMarker.options.icon(BitmapDescriptorFactory.fromBitmap(bitmap))
|
||||
siteNameMarker.position = siteNameMarker.position
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 更新站点信息
|
||||
*/
|
||||
fun updateSiteNameView(index: Int, siteMarkerBean: SiteMarkerBean) {
|
||||
if (siteNameList != null && index in 0 until siteNameList!!.size) {
|
||||
val siteNameMarker = siteNameList!![index]
|
||||
val markerOption = MarkerOptions()
|
||||
markerOption.position(siteMarkerBean.latLng)
|
||||
markerOption.anchor(siteMarkerBean.anchorX, siteMarkerBean.anchorY)
|
||||
markerOption.icon(
|
||||
BitmapDescriptorFactory.fromBitmap(siteMarkerBean.bitmap)
|
||||
)
|
||||
siteNameMarker.setMarkerOptions(markerOption)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 清除站点名
|
||||
*/
|
||||
fun clearSiteNameViews() {
|
||||
if (siteNameList != null) {
|
||||
for (marker in siteNameList!!) {
|
||||
marker.destroy()
|
||||
}
|
||||
siteNameList = null
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 清空线路并隐藏起、终点
|
||||
*/
|
||||
@@ -588,7 +649,7 @@ class OverMapView @JvmOverloads constructor(
|
||||
/**
|
||||
* 进入自定义全览模式
|
||||
*/
|
||||
private fun displayCustomOverView() {
|
||||
fun displayCustomOverView() {
|
||||
val linePointsLatLng = planningPoints
|
||||
if (linePointsLatLng.size > 1 && mLocation != null) {
|
||||
//圈定地图显示范围
|
||||
@@ -661,7 +722,8 @@ class OverMapView @JvmOverloads constructor(
|
||||
* @param coordinates
|
||||
* @param locIndex
|
||||
*/
|
||||
private fun drawPolyline(coordinates: List<LatLng>, locIndex: Int) {
|
||||
@MainThread
|
||||
fun drawPolyline(coordinates: List<LatLng>, locIndex: Int) {
|
||||
if (textureList.size > 0) {
|
||||
textureList.clear()
|
||||
}
|
||||
@@ -702,6 +764,95 @@ class OverMapView @JvmOverloads constructor(
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 绘制站点轨迹线
|
||||
*/
|
||||
@MainThread
|
||||
fun drawSitePolyline(coordinates: List<LatLng>?, bitmap: Bitmap) {
|
||||
if (coordinates.isNullOrEmpty()) return
|
||||
if (mSitePolyline != null) {
|
||||
mSitePolyline!!.remove()
|
||||
}
|
||||
val textureList = arrayListOf<BitmapDescriptor>()
|
||||
val texIndexList = arrayListOf<Int>()
|
||||
for (i in coordinates.indices) {
|
||||
// 线段数比点数少一个
|
||||
if (i == 0) continue
|
||||
textureList.add(BitmapDescriptorFactory.fromBitmap(bitmap))
|
||||
texIndexList.add(i - 1)
|
||||
}
|
||||
if (mAMap != null) {
|
||||
//设置线段纹理
|
||||
val polylineOptions = PolylineOptions()
|
||||
polylineOptions.addAll(coordinates)
|
||||
polylineOptions.width(14f) //线段宽度
|
||||
polylineOptions.lineCapType(PolylineOptions.LineCapType.LineCapRound)
|
||||
polylineOptions.customTextureList = textureList
|
||||
polylineOptions.customTextureIndex = texIndexList
|
||||
// 绘制线
|
||||
mSitePolyline = mAMap!!.addPolyline(polylineOptions)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 清除已选站点的轨迹线
|
||||
*/
|
||||
fun clearSitePolyline() {
|
||||
if (mSitePolyline != null) {
|
||||
mSitePolyline!!.remove()
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 站点轨迹集合被包含在地图显示范围内
|
||||
*/
|
||||
fun includeSitePointsAndUpdateCamera(coordinates: List<LatLng>?) {
|
||||
val linePointsLatLng = planningPoints
|
||||
val boundsBuilder = LatLngBounds.Builder()
|
||||
var isOnlyCarLocation = true
|
||||
|
||||
if (linePointsLatLng.size > 1) {
|
||||
// 圈定地图显示范围(自动驾驶轨迹)
|
||||
for (i in linePointsLatLng.indices) {
|
||||
boundsBuilder.include(linePointsLatLng[i])
|
||||
}
|
||||
isOnlyCarLocation = false
|
||||
}
|
||||
|
||||
if (mLocation != null) {
|
||||
// 自车坐标
|
||||
boundsBuilder.include(LatLng(mLocation!!.latitude, mLocation!!.longitude))
|
||||
}
|
||||
|
||||
coordinates?.let {
|
||||
// 站点轨迹被包含在地图显示范围内
|
||||
for (i in it.indices) {
|
||||
boundsBuilder.include(it[i])
|
||||
}
|
||||
isOnlyCarLocation = false
|
||||
}
|
||||
|
||||
if (!isOnlyCarLocation) {
|
||||
val cameraPosition = CameraPosition.Builder().tilt(mTilt).build()
|
||||
//第二个参数为四周留空宽度
|
||||
mAMap!!.moveCamera(
|
||||
CameraUpdateFactory.newLatLngBoundsRect(
|
||||
boundsBuilder.build(),
|
||||
AutoSizeUtils.dp2px(context, leftPadding.toFloat()),
|
||||
AutoSizeUtils.dp2px(context, rightPadding.toFloat()),
|
||||
AutoSizeUtils.dp2px(context, topPadding.toFloat()),
|
||||
AutoSizeUtils.dp2px(context, bottomPadding.toFloat())
|
||||
)
|
||||
)
|
||||
mAMap!!.moveCamera(CameraUpdateFactory.newCameraPosition(cameraPosition))
|
||||
} else {
|
||||
//设置希望展示的地图缩放级别
|
||||
val cameraPosition = CameraPosition.Builder()
|
||||
.target(mCarMarker!!.position).tilt(mTilt).zoom(zoomLevel.toFloat()).build()
|
||||
mAMap!!.moveCamera(CameraUpdateFactory.newCameraPosition(cameraPosition))
|
||||
}
|
||||
}
|
||||
|
||||
override fun onChassisLocationGCJ02(gnssInfo: MogoLocation?) {
|
||||
gnssInfo?.let {
|
||||
mLocation = it
|
||||
|
||||
Reference in New Issue
Block a user