Merge branch 'master' into release_robosweeper-d_100-sweeper_220830_1.0.0.1_merge

# Conflicts:
#	app_ipc_monitoring/src/main/java/com/zhidao/adas/client/ui/MainActivity.java
#	core/function-impl/mogo-core-function-autopilot/src/main/java/com/mogo/eagle/core/function/autopilot/MoGoAutopilotProvider.kt
#	core/function-impl/mogo-core-function-autopilot/src/main/java/com/mogo/eagle/core/function/autopilot/adapter/MoGoAdasListenerImpl.kt
#	core/function-impl/mogo-core-function-autopilot/src/main/java/com/mogo/eagle/core/function/autopilot/adapter/MoGoAdasMsgConnectStatusListenerImpl.kt
#	core/function-impl/mogo-core-function-hmi/src/main/java/com/mogo/eagle/core/function/hmi/ui/widget/TrafficDataView.java
#	core/function-impl/mogo-core-function-map/src/main/java/com/mogo/eagle/core/function/map/MapPointCloudSubscriber.kt
#	core/mogo-core-function-api/src/main/java/com/mogo/eagle/core/function/api/autopilot/IMoGoAutopilotProvider.kt
#	gradle.properties
#	libraries/mogo-adas-data/src/main/proto/message_pad.proto
#	libraries/mogo-adas-data/src/main/proto/special_vehicle_task_cmd.proto
#	libraries/mogo-adas/src/main/java/com/zhidao/support/adas/high/AdasChannel.java
#	libraries/mogo-adas/src/main/java/com/zhidao/support/adas/high/AdasManager.java
#	libraries/mogo-adas/src/main/java/com/zhidao/support/adas/high/IAdasNetCommApi.java
#	libraries/mogo-adas/src/main/java/com/zhidao/support/adas/high/common/MessageType.java
This commit is contained in:
aibingbing
2022-09-26 19:16:37 +08:00
266 changed files with 9667 additions and 771 deletions

View File

@@ -82,7 +82,6 @@ dependencies {
implementation rootProject.ext.dependencies.androidxconstraintlayout
implementation rootProject.ext.dependencies.androidxrecyclerview
implementation rootProject.ext.dependencies.flexbox
if (Boolean.valueOf(USE_MAVEN_PACKAGE)) {
implementation rootProject.ext.dependencies.mogoserviceapi
implementation rootProject.ext.dependencies.modulecommon

View File

@@ -12,6 +12,7 @@ import com.mogo.eagle.core.data.deva.scene.SceneTAG
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.monitor.MonitorManager
import com.zhjt.mogo_core_function_devatools.scene.SceneManager.Companion.sceneManager
import com.zhjt.mogo_core_function_devatools.status.*
import com.zhjt.mogo_core_function_devatools.trace.TraceManager.Companion.traceManager
@@ -110,4 +111,12 @@ class DevaToolsProvider : IDevaToolsProvider {
override fun hideStatusBar() {
StatusManager.hide()
}
override fun startMonitor() {
mContext?.let { MonitorManager.getInstance(it)?.startMonitor() }
}
override fun stopMonitor() {
mContext?.let { MonitorManager.getInstance(it)?.stopMonitor() }
}
}

View File

@@ -0,0 +1,108 @@
package com.zhjt.mogo_core_function_devatools.monitor
import android.annotation.SuppressLint
import android.content.Context
import android.os.Process
import android.util.Log
import com.zhjt.mogo_core_function_devatools.monitor.db.CpuInfo
import com.zhjt.mogo_core_function_devatools.monitor.db.MonitorDb
import com.zhjt.mogo_core_function_devatools.monitor.utils.CpuUtils
import java.text.SimpleDateFormat
class CpuMonitor private constructor(var context: Context) {
var isRunning = false
private val pid by lazy {
Process.myPid()
}
private val cpuInfoList by lazy {
ArrayList<CpuInfo>()
}
private val dateFormat by lazy {
SimpleDateFormat("yyyy-MM-dd HH:mm:ss")
}
companion object {
private const val TAG = "CpuMonitor"
const val INTERVAL_PERF = 1000L
@SuppressLint("StaticFieldLeak")
@Volatile
private var sInstance: CpuMonitor? = null
fun getInstance(context: Context): CpuMonitor? {
if (sInstance == null) {
synchronized(CpuMonitor::class.java) {
if (sInstance == null) {
sInstance = CpuMonitor(context)
}
}
}
return sInstance
}
}
/**
* 请先运行Shizuku的服务
*/
@Synchronized
fun startRun() {
if (!isRunning) {
Thread(CpuRunnable()).start()
isRunning = true
}
}
@Synchronized
fun isStarted() = isRunning
@Synchronized
fun stop() {
isRunning = false
}
fun saveCpuInfos() {
synchronized(this) {
MonitorDb.getDb(context).monitorDao().saveAllCpuInfos(*cpuInfoList.toTypedArray())
cpuInfoList.clear()
}
}
private fun getCpuValue(): Double {
var value = 0.0
try {
// 应用获取当前进程CPU使用时间Binder服务端获取系统CPU时间中间用耗时不如使用top命令
// value = UserServiceManager.getCpuUsage(Process.myPid())
value = CpuUtils.getCpuUsageForO()
return value
} catch (e: Exception) {
Log.e(TAG, e.message ?: "未知异常!")
}
return value
}
inner class CpuRunnable : Runnable {
override fun run() {
while (isRunning) {
val cpu = getCpuValue()
if (cpu > 0) {
synchronized(this@CpuMonitor) {
cpuInfoList.add(
CpuInfo(
saveTime = dateFormat.format(System.currentTimeMillis()),
cpuPercent = cpu
)
)
}
}
try {
Thread.sleep(INTERVAL_PERF)
} catch (e: InterruptedException) {
e.printStackTrace()
}
}
}
}
}

View File

@@ -0,0 +1,121 @@
package com.zhjt.mogo_core_function_devatools.monitor
import android.annotation.SuppressLint
import android.content.Context
import android.os.Process.myPid
import android.util.Log
import com.zhjt.mogo_core_function_devatools.monitor.db.MemInfo
import com.zhjt.mogo_core_function_devatools.monitor.db.MonitorDb
import com.zhjt.mogo_core_function_devatools.monitor.utils.HookUtils
import com.zhjt.mogo_core_function_devatools.monitor.utils.MemUtils
import java.text.SimpleDateFormat
class MemMonitor private constructor(var context: Context) {
var isRunning = false
private val memInfoList by lazy {
ArrayList<MemInfo>()
}
private val dateFormat by lazy {
SimpleDateFormat("yyyy-MM-dd HH:mm:ss")
}
companion object {
private const val TAG = "MemMonitor"
const val INTERVAL_PERF = 1000L
@SuppressLint("StaticFieldLeak")
@Volatile
private var sInstance: MemMonitor? = null
fun getInstance(context: Context): MemMonitor? {
if (sInstance == null) {
synchronized(MemMonitor::class.java) {
if (sInstance == null) {
sInstance = MemMonitor(context)
}
}
}
return sInstance
}
}
@Synchronized
fun startRun() {
if (!isRunning) {
Thread(MemoryRunnable()).start()
isRunning = true
}
}
@Synchronized
fun isStarted() = isRunning
@Synchronized
fun stop() {
isRunning = false
}
fun saveMemInfos() {
synchronized(this) {
MonitorDb.getDb(context).monitorDao().saveAllMemInfos(*memInfoList.toTypedArray())
memInfoList.clear()
}
}
/**
* 单位MB
*/
private fun getMemoryValue(): Double {
var value = 0.0
try {
value = MemUtils.getPssMemValue(context, intArrayOf(myPid()))
return value
} catch (e: Exception) {
Log.e(TAG, e.message ?: "未知异常!")
}
return value
}
/**
* 单位MB
*/
private fun getMemoryArray(): DoubleArray {
var value = doubleArrayOf()
try {
value = MemUtils.getPssArray(context, intArrayOf(myPid()))
return value
} catch (e: Exception) {
Log.e(TAG, e.message ?: "未知异常!")
}
return value
}
inner class MemoryRunnable : Runnable {
override fun run() {
while (isRunning) {
// 0: 总PSS1: dalvik总Pss, 2: native总Pss, 3: other总Pss
val pssArray = getMemoryArray()
if (pssArray[0] > 0) {
synchronized(this@MemMonitor) {
memInfoList.add(
MemInfo(
saveTime = dateFormat.format(System.currentTimeMillis()),
totalPss = pssArray[0],
dalvikPss = pssArray[1],
nativePss = pssArray[2],
otherPss = pssArray[3]
)
)
}
}
try {
Thread.sleep(INTERVAL_PERF)
} catch (e: InterruptedException) {
e.printStackTrace()
}
}
}
}
}

View File

@@ -0,0 +1,64 @@
package com.zhjt.mogo_core_function_devatools.monitor
import android.annotation.SuppressLint
import android.content.Context
import android.os.Looper
import com.mogo.eagle.core.utilcode.util.ToastUtils
import java.util.*
class MonitorManager private constructor(var context: Context) {
private var timer: Timer? = null
private var isStarted = false
companion object {
@SuppressLint("StaticFieldLeak")
@Volatile
private var sInstance: MonitorManager? = null
fun getInstance(context: Context): MonitorManager? {
if (sInstance == null) {
synchronized(MonitorManager::class.java) {
if (sInstance == null) {
sInstance = MonitorManager(context)
}
}
}
return sInstance
}
}
/**
* 主线程中执行
*/
fun startMonitor() {
if (Thread.currentThread() == Looper.getMainLooper().thread) {
if (!isStarted) {
CpuMonitor.getInstance(context)?.startRun()
MemMonitor.getInstance(context)?.startRun()
if (timer == null) {
timer = Timer()
}
timer!!.schedule(object : TimerTask() {
override fun run() {
CpuMonitor.getInstance(context)?.saveCpuInfos()
MemMonitor.getInstance(context)?.saveMemInfos()
}
}, 1000, 60000)
isStarted = true
ToastUtils.showShort("性能监控启动成功!")
} else {
ToastUtils.showShort("性能监控已启动,请勿重复启动!")
}
}
}
fun stopMonitor() {
CpuMonitor.getInstance(context)?.stop()
MemMonitor.getInstance(context)?.stop()
timer?.cancel()
timer = null
isStarted = false
ToastUtils.showShort("性能监控停止成功!")
}
}

View File

@@ -0,0 +1,18 @@
package com.zhjt.mogo_core_function_devatools.monitor.db
import androidx.room.ColumnInfo
import androidx.room.Entity
import androidx.room.PrimaryKey
@Entity(tableName = "t_cpu")
data class CpuInfo(
@PrimaryKey(autoGenerate = true)
@ColumnInfo(name = "id")
val uuid: Long = 0,
@ColumnInfo(name = "save_time")
val saveTime: String?,
@ColumnInfo(name = "cpu_percent")
val cpuPercent: Double
)

View File

@@ -0,0 +1,27 @@
package com.zhjt.mogo_core_function_devatools.monitor.db
import androidx.room.ColumnInfo
import androidx.room.Entity
import androidx.room.PrimaryKey
@Entity(tableName = "t_memory")
data class MemInfo(
@PrimaryKey(autoGenerate = true)
@ColumnInfo(name = "id")
val uuid: Long = 0,
@ColumnInfo(name = "save_time")
val saveTime: String,
@ColumnInfo(name = "total_pss")
val totalPss: Double,
@ColumnInfo(name = "dalvik_pss")
val dalvikPss: Double,
@ColumnInfo(name = "native_pss")
val nativePss: Double,
@ColumnInfo(name = "other_pss")
val otherPss: Double
)

View File

@@ -0,0 +1,24 @@
package com.zhjt.mogo_core_function_devatools.monitor.db
import androidx.room.*
@Dao
interface MonitorDao {
@Insert(onConflict = OnConflictStrategy.REPLACE)
fun saveCpu(info: CpuInfo)
@Insert(onConflict = OnConflictStrategy.REPLACE)
fun saveAllCpuInfos(vararg cpuInfo: CpuInfo)
@Insert(onConflict = OnConflictStrategy.REPLACE)
fun saveMemory(info: MemInfo)
@Insert(onConflict = OnConflictStrategy.REPLACE)
fun saveAllMemInfos(vararg memInfo: MemInfo)
@Query("SELECT * FROM t_cpu WHERE id =:id")
fun getAllCPUById(id: Long): List<CpuInfo>
@Query("SELECT * FROM t_memory WHERE id =:id")
fun getAllMemById(id: Long): List<MemInfo>
}

View File

@@ -0,0 +1,27 @@
package com.zhjt.mogo_core_function_devatools.monitor.db
import android.content.Context
import androidx.room.Database
import androidx.room.Room
import androidx.room.RoomDatabase
@Database(entities = [CpuInfo::class, MemInfo::class], version = 1, exportSchema = false)
abstract class MonitorDb: RoomDatabase() {
abstract fun monitorDao(): MonitorDao
companion object {
const val INTERNAL_DB_NAME = "mogo_monitor.db"
private var db: MonitorDb? = null
@JvmStatic
fun getDb(context: Context): MonitorDb {
if (db == null) {
db = Room.databaseBuilder(context.applicationContext, MonitorDb::class.java, INTERNAL_DB_NAME)
.fallbackToDestructiveMigration()
.build()
}
return db!!
}
}
}

View File

@@ -0,0 +1,17 @@
package com.zhjt.mogo_core_function_devatools.monitor.remote;
import android.os.IBinder;
import android.os.IInterface;
import android.os.RemoteException;
public interface IUserInterface extends IInterface {
String DESCRIPTOR = "rikka.shizuku.demo.IUserInterface";
int TRANSACTION_exec = IBinder.FIRST_CALL_TRANSACTION;
int TRANSACTION_getCpuUsage = IBinder.FIRST_CALL_TRANSACTION + 1;
String exec(String cmd) throws RemoteException;
double getCpuUsage(int pid) throws RemoteException;
}

View File

@@ -0,0 +1,141 @@
package com.zhjt.mogo_core_function_devatools.monitor.remote;
import android.os.Binder;
import android.os.IBinder;
import android.os.IInterface;
import android.os.Parcel;
import android.os.RemoteException;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import com.zhjt.mogo_core_function_devatools.monitor.utils.CpuUtils;
/**
* Server端Binder类
*/
public class RemoteUserServiceImp extends Binder implements IUserInterface {
public RemoteUserServiceImp() {
attachInterface(this, DESCRIPTOR);
}
public static IUserInterface asInterface(IBinder obj) {
if ((obj == null)) {
return null;
}
IInterface iin = obj.queryLocalInterface(DESCRIPTOR);
if (iin instanceof IUserInterface) {
return ((IUserInterface) iin);
}
return new Proxy(obj);
}
@Override
public String exec(String cmd) throws RemoteException {
return "";
}
@Override
public double getCpuUsage(int pid) throws RemoteException {
return CpuUtils.getCpuUsagePercentWithPid(pid);
}
/**
* 处理Client端请求
*
* @param code
* @param data
* @param reply
* @param flags
* @return
* @throws RemoteException
*/
@Override
protected boolean onTransact(int code, @NonNull Parcel data, @Nullable Parcel reply, int flags) throws RemoteException {
final String descriptor = DESCRIPTOR;
switch (code) {
case TRANSACTION_exec:
data.enforceInterface(descriptor);
String _arg0;
_arg0 = data.readString();
String _result = this.exec(_arg0);
reply.writeNoException();
reply.writeString(_result);
return true;
default:
return super.onTransact(code, data, reply, flags);
}
}
@Nullable
@Override
public String getInterfaceDescriptor() {
return super.getInterfaceDescriptor();
}
/**
* 返回给Client端并被封装成BinderProxy
*
* @return
*/
@Override
public IBinder asBinder() {
return this;
}
public static class Proxy implements IUserInterface {
private IBinder mRemote;
public Proxy(IBinder remote) {
mRemote = remote;
}
public String getInterfaceDescriptor() {
return DESCRIPTOR;
}
@Override
public IBinder asBinder() {
// 返回Server端Binder对象
return mRemote;
}
@Override
public String exec(String cmd) throws RemoteException {
// 参数传递给Server端并挂起当前线程等待Server端执行完返回结果
Parcel _data = Parcel.obtain();
Parcel _reply = Parcel.obtain();
String _result;
try {
_data.writeInterfaceToken(DESCRIPTOR);
_data.writeString(cmd);
mRemote.transact(TRANSACTION_exec, _data, _reply, 0);
_reply.readException();
_result = _reply.readString();
} finally {
_reply.recycle();
_data.recycle();
}
return _result;
}
@Override
public double getCpuUsage(int pid) throws RemoteException {
Parcel _data = Parcel.obtain();
Parcel _reply = Parcel.obtain();
double _result;
try {
_data.writeInterfaceToken(DESCRIPTOR);
_data.writeInt(pid);
mRemote.transact(TRANSACTION_getCpuUsage, _data, _reply, 0);
_reply.readException();
_result = _reply.readDouble();
} finally {
_reply.recycle();
_data.recycle();
}
return _result;
}
}
}

View File

@@ -0,0 +1,182 @@
package com.zhjt.mogo_core_function_devatools.monitor.remote
//import rikka.shizuku.Shizuku
//import android.content.ServiceConnection
//import android.content.ComponentName
//import android.os.IBinder
//import rikka.shizuku.Shizuku.UserServiceArgs
//import android.content.pm.PackageManager
//import android.util.Log
//import com.mogo.eagle.core.utilcode.util.AppUtils
//import com.mogo.eagle.core.utilcode.util.ToastUtils
//import rikka.shizuku.Shizuku.OnBinderReceivedListener
//import rikka.shizuku.Shizuku.OnBinderDeadListener
//import rikka.shizuku.Shizuku.OnRequestPermissionResultListener
//import java.lang.StringBuilder
object UserServiceManager {
// private const val TAG = "UserServiceManager"
// private const val REQUEST_CODE_BIND = 1
// private const val REQUEST_CODE_UNBIND = 2
//
// private var userServiceProxy: IUserInterface? = null
// private var isFirst = true
//
// fun init() {
// if (isFirst) {
// addListener()
// isFirst = false
// }
// bindUserService()
// }
//
// fun stopService() {
// removeListener()
// unbindUserService()
// }
//
// fun isServiceActive(): Boolean {
// var isActive = false
// val service = userServiceProxy
// if (service != null && service is IBinder && service.isBinderAlive) {
// isActive = true
// }
// return isActive
// }
//
// private fun addListener() {
// Shizuku.addBinderReceivedListenerSticky(BINDER_RECEIVED_LISTENER)
// Shizuku.addBinderDeadListener(BINDER_DEAD_LISTENER)
// Shizuku.addRequestPermissionResultListener(REQUEST_PERMISSION_RESULT_LISTENER)
// }
//
// private fun removeListener() {
// Shizuku.removeBinderReceivedListener(BINDER_RECEIVED_LISTENER)
// Shizuku.removeBinderDeadListener(BINDER_DEAD_LISTENER)
// Shizuku.removeRequestPermissionResultListener(REQUEST_PERMISSION_RESULT_LISTENER)
// }
//
// private fun bindUserService() {
// if (checkPermission(REQUEST_CODE_BIND)) {
// val res = StringBuilder()
// try {
// if (Shizuku.getVersion() < 10) {
// res.append("requires Shizuku API 10")
// } else {
// Shizuku.bindUserService(userServiceArgs, userServiceConnection)
// }
// } catch (tr: Throwable) {
// tr.printStackTrace()
// res.append(tr.toString())
// }
// }
// }
//
// private fun unbindUserService() {
// if (checkPermission(REQUEST_CODE_UNBIND)) {
// val res = StringBuilder()
// try {
// if (Shizuku.getVersion() < 10) {
// res.append("requires Shizuku API 10")
// } else {
// Shizuku.unbindUserService(userServiceArgs, userServiceConnection, true)
// }
// } catch (tr: Throwable) {
// tr.printStackTrace()
// res.append(tr.toString())
// }
// }
// }
//
// fun exec(cmd: String): String {
// return userServiceProxy?.exec(cmd) ?: ""
// }
//
// /**
// * 单位:%保留1位小数
// */
// fun getCpuUsage(pid: Int): Double {
// return userServiceProxy?.getCpuUsage(pid) ?: -1.0
// }
//
// private val userServiceConnection: ServiceConnection = object : ServiceConnection {
// override fun onServiceConnected(componentName: ComponentName, binder: IBinder?) {
// if (binder != null && binder.pingBinder()) {
// val service = RemoteUserServiceImp.asInterface(binder)
// userServiceProxy = service
// ToastUtils.showShort("监控权限获取成功!")
// }
// }
//
// override fun onServiceDisconnected(componentName: ComponentName) {}
// }
//
// private val userServiceArgs by lazy {
// val appInfo = AppUtils.getAppInfo()
// UserServiceArgs(
// ComponentName(
// appInfo?.packageName ?: "com.mogo.launcher.f",
// RemoteUserServiceImp::class.java.name
// )
// )
// .daemon(false)
// .processNameSuffix("service")
// .debuggable(true)
// .version(appInfo?.versionCode ?: 1)
// }
//
// private fun checkPermission(code: Int): Boolean {
// if (Shizuku.isPreV11()) {
// Log.w(TAG, "Version is preV11!")
// return false
// }
// try {
// return if (Shizuku.checkSelfPermission() == PackageManager.PERMISSION_GRANTED) {
// true
// } else if (Shizuku.shouldShowRequestPermissionRationale()) {
// Log.e(TAG, "User denied permission (shouldShowRequestPermissionRationale=true)")
// false
// } else {
// Shizuku.requestPermission(code)
// false
// }
// } catch (e: Throwable) {
// Log.e(TAG, Log.getStackTraceString(e))
// ToastUtils.showLong("请先打开Shizuku并启动它")
// }
// return false
// }
//
// private fun onRequestPermissionsResult(requestCode: Int, grantResult: Int) {
// if (grantResult == PackageManager.PERMISSION_GRANTED) {
// when (requestCode) {
// REQUEST_CODE_BIND -> {
// bindUserService()
// }
// REQUEST_CODE_UNBIND -> {
// unbindUserService()
// }
// else -> {}
// }
// } else {
// Log.e(TAG, "User denied permission")
// }
// }
//
// private val BINDER_RECEIVED_LISTENER = OnBinderReceivedListener {
// if (Shizuku.isPreV11()) {
// Log.w(TAG, "Shizuku pre-v11 is not supported")
// } else {
// Log.d(TAG, "Binder received")
// }
// }
// private val BINDER_DEAD_LISTENER = OnBinderDeadListener { Log.w(TAG, "Binder dead") }
// private val REQUEST_PERMISSION_RESULT_LISTENER =
// OnRequestPermissionResultListener { requestCode: Int, grantResult: Int ->
// onRequestPermissionsResult(
// requestCode,
// grantResult
// )
// }
}

View File

@@ -0,0 +1,298 @@
package com.zhjt.mogo_core_function_devatools.monitor.utils;
import android.os.Process;
import android.text.TextUtils;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.RandomAccessFile;
/**
* CPU相关工具类。
*/
public class CpuUtils {
private static boolean initCpu = true;
private static double oCpu = 0.0;
private static double oIdle = 0.0;
private static double pJif = 0.0;
private static double pCpu = 0.0;
private static double aCpu = 0.0;
private static double opCpu = 0.0;
private static double oaCpu = 0.0;
/**
* 8.0以上获取cpu的方式
*
* @return
*/
public static double getCpuUsageForO() {
java.lang.Process process = null;
try {
process = Runtime.getRuntime().exec("top -n 1");
BufferedReader reader = new BufferedReader(new InputStreamReader(process.getInputStream()));
String line;
int cpuIndex = -1;
while ((line = reader.readLine()) != null) {
line = line.trim();
if (TextUtils.isEmpty(line)) {
continue;
}
int tempIndex = getCPUIndex(line);
if (tempIndex != -1) {
cpuIndex = tempIndex;
continue;
}
if (line.startsWith(String.valueOf(Process.myPid()))) {
if (cpuIndex == -1) {
continue;
}
String[] param = line.split("\\s+");
if (param.length <= cpuIndex) {
continue;
}
String cpu = param[cpuIndex];
if (cpu.endsWith("%")) {
cpu = cpu.substring(0, cpu.lastIndexOf("%"));
}
return Double.parseDouble(cpu) / Runtime.getRuntime().availableProcessors();
}
}
} catch (IOException e) {
e.printStackTrace();
} finally {
if (process != null) {
process.destroy();
}
}
return 0;
}
private static int getCPUIndex(String line) {
if (line.contains("CPU")) {
String[] titles = line.split("\\s+");
for (int i = 0; i < titles.length; i++) {
if (titles[i].contains("CPU")) {
return i;
}
}
}
return -1;
}
/**
* 获取应用的CPU占用率单位%保留1位小数
* @param pid
* @return
*/
public static double getCpuUsagePercentWithPid(int pid) {
double usage = 0.0;
String[] result1;
String[] result2;
if (pid >= 0) {
result1 = getCpuWithPid(pid);
if (null != result1) {
pCpu = Double.parseDouble(result1[1])
+ Double.parseDouble(result1[2]);
}
result2 = getSystemCpu();
if (null != result2) {
aCpu = 0.0;
for (int i = 2; i < result2.length; i++) {
if (result2[i] != null) {
aCpu += Double.parseDouble(result2[i]);
}
}
}
if ((aCpu - oaCpu) != 0) {
usage = DoubleUtils.div(((pCpu - opCpu) * 100.00),
(aCpu - oaCpu), 1);
if (usage < 0) {
usage = 0;
}
else if (usage > 100)
{
usage = 100;
}
}
opCpu = pCpu;
oaCpu = aCpu;
}
pJif = pCpu;
return usage;
}
/**
* 获取CPU使用率
*
* @return CPU使用率单位%
*/
public static double getSysCpuUsagePercent() {
double usage = 0.0;
if (initCpu) {
initCpu = false;
RandomAccessFile reader = null;
try {
reader = new RandomAccessFile("/proc/stat",
"r");
String load;
load = reader.readLine();
String[] toks = load.split(" ");
oIdle = Double.parseDouble(toks[5]);
oCpu = Double.parseDouble(toks[2])
+ Double.parseDouble(toks[3])
+ Double.parseDouble(toks[4])
+ Double.parseDouble(toks[6])
+ Double.parseDouble(toks[8])
+ Double.parseDouble(toks[7]);
} catch (IOException e) {
e.printStackTrace();
}
finally
{
FileUtil.closeRandomAccessFile(reader);
}
} else {
RandomAccessFile reader = null;
try {
reader = new RandomAccessFile("/proc/stat", "r");
String load;
load = reader.readLine();
String[] toks = load.split(" ");
double cIdle = Double.parseDouble(toks[5]);
double cCpu = Double.parseDouble(toks[2])
+ Double.parseDouble(toks[3])
+ Double.parseDouble(toks[4])
+ Double.parseDouble(toks[6])
+ Double.parseDouble(toks[8])
+ Double.parseDouble(toks[7]);
if (0 != ((cCpu + cIdle) - (oCpu + oIdle))) {
usage = DoubleUtils.div((100.00 * ((cCpu - oCpu))),
((cCpu + cIdle) - (oCpu + oIdle)), 1);
if (usage < 0) {
usage = 0;
}
else if (usage > 100)
{
usage = 100;
}
}
oCpu = cCpu;
oIdle = cIdle;
} catch (IOException e) {
e.printStackTrace();
} finally {
FileUtil.closeRandomAccessFile(reader);
}
}
return usage;
}
private static String[] getCpuWithPid(int pid) {
String cpuPath = "/proc/" + pid + "/stat";
String cpu = "";
String[] result = new String[3];
File f = new File(cpuPath);
// 部分进程信息无法读取
if (!f.exists() || !f.canRead())
{
return result;
}
FileReader fr = null;
BufferedReader localBufferedReader = null;
try {
fr = new FileReader(f);
localBufferedReader = new BufferedReader(fr, 8192);
cpu = localBufferedReader.readLine();
if (null != cpu) {
String[] cpuSplit = cpu.split(" ");
result[0] = cpuSplit[1];
result[1] = cpuSplit[13];
result[2] = cpuSplit[14];
}
}catch (IOException e) {
e.printStackTrace();
}
FileUtil.closeReader(localBufferedReader);
return result;
}
private static String[] getSystemCpu() {
String cpuPath = "/proc/stat";
String cpu = "";
String[] result = new String[7];
File f = new File(cpuPath);
if (!f.exists() || !f.canRead())
{
return result;
}
FileReader fr = null;
BufferedReader localBufferedReader = null;
try {
fr = new FileReader(f);
localBufferedReader = new BufferedReader(fr, 8192);
cpu = localBufferedReader.readLine();
if (null != cpu) {
result = cpu.split(" ");
}
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
FileUtil.closeReader(localBufferedReader);
return result;
}
public static String getCpuUsageByCmd() {
java.lang.Process process;
StringBuilder sb = new StringBuilder();
String line;
String cmd = "dumpsys cpuinfo";
try {
process = Runtime.getRuntime().exec(
new String[] { "sh", "-c", cmd });
BufferedReader br = new BufferedReader(new InputStreamReader(
process.getInputStream()));
while (((line = br.readLine()) != null)) {
// 去掉空白行数据
line = line.trim();
if (line.equals("")) {
continue;
}
sb.append(line);
sb.append("\r\n");
}
try {
process.waitFor();
} catch (InterruptedException e) {
e.printStackTrace();
}
} catch (IOException e) {
e.printStackTrace();
}
return sb.toString();
}
/**
* 获取进程的CPU使用时间片
*
* @return 进程的CPU使用时间片
*/
public long getJif() {
return (long)pJif;
}
}

View File

@@ -0,0 +1,44 @@
package com.zhjt.mogo_core_function_devatools.monitor.utils
import java.lang.Exception
import java.math.BigDecimal
object DoubleUtils {
fun mul(d1: Double, d2: Double): Double {
val bd1 = BigDecimal(d1.toString())
val bd2 = BigDecimal(d2.toString())
return try {
bd1.multiply(bd2).toDouble()
} catch (e: Exception) {
e.printStackTrace()
0.0
}
}
@JvmStatic
fun div(d1: Double, d2: Double, scale: Int): Double {
val bd1 = BigDecimal(d1.toString())
val bd2 = BigDecimal(d2.toString())
return try {
// 直接向下取整
bd1.divide(bd2, scale, BigDecimal.ROUND_DOWN).toDouble()
} catch (e: Exception) {
e.printStackTrace()
0.0
}
}
/**
* 四舍五入
* scale:保留多少个小数位
*/
@JvmStatic
fun keepDecimal(v: Double, scale: Int = 1): Double {
if (scale < 0) {
throw IllegalArgumentException("The scale must be a positive integer or zero")
}
return BigDecimal(v).setScale(scale, BigDecimal.ROUND_HALF_UP).toDouble()
}
}

View File

@@ -0,0 +1,304 @@
package com.zhjt.mogo_core_function_devatools.monitor.utils
import android.net.LocalSocket
import android.util.Log
import java.io.*
import java.lang.Exception
import java.net.Socket
import java.nio.channels.FileChannel
object FileUtil {
private const val TAG = "FileUtil"
const val separator = "/"
fun isPathStringValid(path: String?): Boolean {
if (null == path || path.isEmpty()) {
return false
}
if (path.contains(":") || path.contains("*") || path.contains("?")
|| path.contains("\"") || path.contains("<")
|| path.contains(">") || path.contains("|")
) {
Log.w(TAG, "filename can not contains:*:?\"<>|")
return false
}
return true
}
fun isPath(path: String): Boolean {
return path.contains(separator) || path.contains("\\")
}
fun getPath(path: String): String {
val la = path.lastIndexOf(separator)
return path.substring(0, la)
}
fun convertValidFilePath(path: String, defPosfix: String): String {
var filePath = path
if (path.contains(separator) || path.contains("\\")) {
val la = filePath.lastIndexOf(".")
if (la < 0) {
filePath = path + defPosfix
} else {
val temp = filePath.substring(la)
if (temp.contains(separator) || temp.contains("\\")) {
// "."是目录名的一部分而不是后缀名的情况
filePath = path + defPosfix
}
// else fileName = fileName
}
} else {
if (!path.contains(".")) // 没有有后缀
{
filePath = filePath + defPosfix
}
}
return filePath
}
fun isFileExists(file: String?): Boolean {
try {
val f = File(file)
if (!f.exists()) {
return false
}
} catch (e: Exception) {
e.printStackTrace()
return false
}
return true
}
fun isFileValid(f: File): Boolean {
if (!f.exists()) {
try {
f.createNewFile()
} catch (e: IOException) {
return false
}
f.delete()
}
return true
}
fun isFileValid(parent: File?, name: String?): Boolean {
val f = File(parent, name)
return isFileValid(f)
}
/**
* 删除存在的文件
*
* @param filePath
*/
fun delExistFile(filePath: String?) {
val f = File(filePath)
if (f.exists()) f.delete()
}
/**
* 关闭bufferReader
*
* @param br
*/
@JvmStatic
fun closeReader(br: Reader?) {
if (br != null) {
try {
br.close()
} catch (e: IOException) {
e.printStackTrace()
}
}
}
/**
* 关闭Writer
*
* @param wr
*/
fun closeWriter(wr: Writer?) {
if (wr != null) {
try {
wr.close()
} catch (e: IOException) {
e.printStackTrace()
}
}
}
/**
* flush Writer
*
* @param wr
*/
fun flushWriter(wr: Writer?) {
if (wr != null) {
try {
wr.flush()
} catch (e: IOException) {
e.printStackTrace()
}
}
}
/**
* 输入流的关闭
*
* @param in
*/
fun closeInputStream(`in`: InputStream?) {
if (`in` != null) {
try {
`in`.close()
} catch (e: IOException) {
e.printStackTrace()
}
}
}
/**
* 输出流的关闭
*
* @param out
*/
fun closeOutputStream(out: OutputStream?) {
if (out != null) {
try {
out.close()
} catch (e: IOException) {
e.printStackTrace()
}
}
}
/**
* 文件管道的关闭
*
* @param chl
*/
fun closeFileChannel(chl: FileChannel?) {
if (chl != null) {
try {
chl.close()
} catch (e: IOException) {
e.printStackTrace()
}
}
}
/**
* RandomAccessFile的关闭
*
* @param f RandomAccessFile对象
*/
@JvmStatic
fun closeRandomAccessFile(f: RandomAccessFile?) {
if (f != null) {
try {
f.close()
} catch (e: IOException) {
e.printStackTrace()
}
}
}
/**
* Socket的关闭
*
* @param s Socket对象
*/
fun colseSocket(s: Socket?) {
if (s != null) {
try {
s.close()
} catch (e: IOException) {
e.printStackTrace()
}
}
}
/**
* LocalSocket的关闭
*
* @param s Socket对象
*/
fun colseLocalSocket(s: LocalSocket?) {
if (s != null) {
try {
s.close()
} catch (e: IOException) {
e.printStackTrace()
}
}
}
fun deleteFile(file: File) {
if (file.exists()) { // 判断文件是否存在
if (file.isFile) { // 判断是否是文件
file.delete() // delete()方法 你应该知道 是删除的意思;
} else if (file.isDirectory) { // 否则如果它是一个目录
val files = file.listFiles() // 声明目录下所有的文件 files[];
for (i in files.indices) { // 遍历目录下所有的文件
deleteFile(files[i]) // 把每个文件 用这个方法进行迭代
}
}
file.delete()
} else {
Log.e(TAG, "文件不存在!" + "n")
}
}
/**
* 拷贝文件
*
* @param s 源文件
* @param t 目标文件
*/
fun copyFile(s: File?, t: File) {
var fi: FileInputStream? = null
var fo: FileOutputStream? = null
var `in`: FileChannel? = null
var out: FileChannel? = null
try {
if (!t.exists()) {
t.createNewFile()
}
fi = FileInputStream(s)
fo = FileOutputStream(t)
`in` = fi.channel
out = fo.channel
// 连接两个通道并且从in通道读取然后写入out通道
`in`.transferTo(0, `in`.size(), out)
} catch (e: IOException) {
e.printStackTrace()
} finally {
closeOutputStream(fo)
closeInputStream(fi)
closeFileChannel(`in`)
closeFileChannel(out)
}
}
fun copyInputToFile(`in`: InputStream?, path: String?) {
var bis: BufferedInputStream? = null
var fos: FileOutputStream? = null
try {
val buffer = ByteArray(10 * 1024)
bis = BufferedInputStream(`in`)
fos = FileOutputStream(path)
var a = bis.read(buffer, 0, buffer.size)
while (a != -1) {
fos.write(buffer, 0, a)
fos.flush()
a = bis.read(buffer, 0, buffer.size)
}
} catch (e: Exception) {
e.printStackTrace()
} finally {
closeOutputStream(fos)
closeInputStream(bis)
closeInputStream(`in`)
}
}
}

View File

@@ -0,0 +1,54 @@
package com.zhjt.mogo_core_function_devatools.monitor.utils;
import android.os.Debug;
import android.util.Log;
import java.lang.reflect.Field;
public class HookUtils {
private static final String TAG = "HookUtils";
/**
* 单位为MB
* 0: 总PSS1: dalvik总Pss, 2: native总Pss, 3: other总Pss
* @param memoryInfo
* @return
*/
public static double[] getPssArray(Debug.MemoryInfo memoryInfo) {
double[] pssArray = new double[4];
if (memoryInfo != null) {
double totalPss = DoubleUtils.keepDecimal(memoryInfo.getTotalPss() / 1024.0, 3);
// Log.d(TAG, "===========Hook PSS 开始:===========\n");
// Log.d(TAG, "总PSS内存为" + totalPss);
pssArray[0] = totalPss;
try {
Field dalvikField = memoryInfo.getClass().getField("dalvikSwappedOutPss");
double dalvikPss = DoubleUtils.keepDecimal(memoryInfo.dalvikPss / 1024.0, 3);
double dalvikSwappedOutPss = DoubleUtils.keepDecimal((int) dalvikField.get(memoryInfo) / 1024.0, 3);
pssArray[1] = dalvikPss + dalvikSwappedOutPss;
// Log.d(TAG, "dalvikPss is:" + dalvikSwappedOutPss);
// Log.d(TAG, "dalvikSwappedOutPss is:" + dalvikPss + "\n\n");
Field nativeField = memoryInfo.getClass().getField("nativeSwappedOutPss");
double nativePss = DoubleUtils.keepDecimal(memoryInfo.nativePss / 1024.0, 3);
double nativeSwappedOutPss = DoubleUtils.keepDecimal((int) nativeField.get(memoryInfo) / 1024.0, 3);
pssArray[2] = nativePss + nativeSwappedOutPss;
// Log.d(TAG, "nativePss is:" + nativePss);
// Log.d(TAG, "nativeSwappedOutPss is:" + nativeSwappedOutPss + "\n\n");
Field otherField = memoryInfo.getClass().getField("otherSwappedOutPss");
double otherPss = DoubleUtils.keepDecimal(memoryInfo.otherPss / 1024.0, 3);
double otherSwappedOutPss = DoubleUtils.keepDecimal((int) otherField.get(memoryInfo) / 1024.0, 3);
pssArray[3] = otherPss + otherSwappedOutPss;
// Log.d(TAG, "otherPss is:" + otherPss);
// Log.d(TAG, "otherSwappedOutPss is:" + otherSwappedOutPss + "\n\n");
//
// Log.d(TAG, "===========Hook PSS 结束!===========\n");
} catch (Exception e) {
e.printStackTrace();
Log.e(TAG, e.getMessage());
}
}
return pssArray;
}
}

View File

@@ -0,0 +1,180 @@
package com.zhjt.mogo_core_function_devatools.monitor.utils;
import android.app.ActivityManager;
import android.content.Context;
import android.os.Debug;
import java.lang.reflect.Method;
/**
* 内存信息工具类。
*/
public class MemUtils {
public static double[] getPssArray(Context context, int[] pids) {
Debug.MemoryInfo[] memoryArray = getMemoryInfo(context, pids);
if (memoryArray.length > 0) {
return HookUtils.getPssArray(memoryArray[0]);
} else {
return new double[4];
}
}
/**
* 单位MB
*/
public static double getPssMemValue(Context context, int[] pids) {
double value = 0.0;
Debug.MemoryInfo[] memoryArray = getMemoryInfo(context, pids);
if (memoryArray.length > 0) {
value = DoubleUtils.keepDecimal(memoryArray[0].getTotalPss() / 1024.0, 1);
}
return value;
}
/**
* 只能获取本应用的PSS内存占系统百分比单位%保留1位小数
* @return
*/
public static double getPidMemPercent() {
double percent = 0.0;
Debug.MemoryInfo memInfo = new Debug.MemoryInfo();
Debug.getMemoryInfo(memInfo);
int pidTotalPss = memInfo.getTotalPss();
long systemTotalMem = getTotalMem();
percent = DoubleUtils.keepDecimal(pidTotalPss * 100.0 / systemTotalMem, 1);
return percent;
}
/**
* 获取本应用进程总pss内存单位MB
*/
public static double getPssMem() {
Debug.MemoryInfo memInfo = new Debug.MemoryInfo();
Debug.getMemoryInfo(memInfo);
return DoubleUtils.keepDecimal(memInfo.getTotalPss() / 1024.0, 1);
}
/**
* 获取系统空闲内存占用百分比: 单位%
* @return
*/
public static double getSystemMemPercent() {
double percent = 0.0;
long[] memInfo = getMemInfo();
long free = memInfo[1] + memInfo[2] + memInfo[3];
long total = memInfo[0];
percent = DoubleUtils.keepDecimal(free * 100.0 / total, 1);
return percent;
}
/**
* 获取空闲内存
*
* @return 空闲内存单位KB
*/
public static long getFreeMem() {
long[] memInfo = getMemInfo();
return memInfo[1] + memInfo[2] + memInfo[3];
}
/**
* 获取总内存
*
* @return 总内存单位KB
*/
public static long getTotalMem() {
long[] memInfo = getMemInfo();
return memInfo[0];
}
/**
* 获取内存信息total、free、buffers、cached单位KB
*
* @return 内存信息
*/
public static long[] getMemInfo() {
long memInfo[] = new long[4];
try {
Class<?> procClazz = Class.forName("android.os.Process");
Class<?> paramTypes[] = new Class[] { String.class, String[].class,
long[].class };
Method readProclines = procClazz.getMethod("readProcLines",
paramTypes);
Object args[] = new Object[3];
final String[] memInfoFields = new String[] { "MemTotal:",
"MemFree:", "Buffers:", "Cached:" };
long[] memInfoSizes = new long[memInfoFields.length];
memInfoSizes[0] = 30;
memInfoSizes[1] = -30;
args[0] = "/proc/meminfo";
args[1] = memInfoFields;
args[2] = memInfoSizes;
if (null != readProclines) {
readProclines.invoke(null, args);
for (int i = 0; i < memInfoSizes.length; i++) {
memInfo[i] = memInfoSizes[i];
}
}
} catch (Exception e) {
e.printStackTrace();
}
return memInfo;
}
public static long[] getHeapNative() {
int Native_HeapSize = 0;
int Native_HeapAlloc = 1;
long[] value = new long[2];
value[Native_HeapSize] = Debug.getNativeHeapSize() >> 10;
value[Native_HeapAlloc] = Debug.getNativeHeapAllocatedSize() >> 10;
return value;
}
public static long[] getHeapDalvik() {
int Total_HeapSize = 0;
int Total_HeapAlloc = 1;
long[] value_total = new long[2];
value_total[Total_HeapSize] = Runtime.getRuntime().totalMemory() >> 10;
value_total[Total_HeapAlloc] = (Runtime.getRuntime().totalMemory() - Runtime
.getRuntime().freeMemory()) >> 10;
long[] value_native = getHeapNative();
int Dalvik_HeapSize = 0;
int Dalvik_HeapAlloc = 1;
long[] value_dalvik = new long[2];
value_dalvik[Dalvik_HeapSize] = value_total[Total_HeapSize]
- value_native[0];
value_dalvik[Dalvik_HeapAlloc] = value_total[Total_HeapAlloc]
- value_native[1];
return value_dalvik;
}
/**
* 获取堆内存数据精确到KB Get VM Heap Size by calling:
* Runtime.getRuntime().totalMemory(); Get Allocated VM Memory by calling:
* Runtime.getRuntime().totalMemory() - Runtime.getRuntime().freeMemory();
* Get VM Heap Size Limit by calling: Runtime.getRuntime().maxMemory() Get
* Native Allocated Memory by calling: Debug.getNativeHeapAllocatedSize();
*/
public static long[] getVM() {
long[] value = new long[5];
value[0] = (Runtime.getRuntime().totalMemory() - Runtime.getRuntime()
.freeMemory()) >> 10;
value[1] = Runtime.getRuntime().totalMemory() >> 10;
value[2] = Debug.getNativeHeapAllocatedSize() >> 10;
value[3] = Debug.getNativeHeapSize() >> 10;
value[4] = Debug.getGlobalAllocSize() >> 10;
return value;
}
private static Debug.MemoryInfo[] getMemoryInfo(Context context, int[] pids) {
ActivityManager am = (ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE);
return am.getProcessMemoryInfo(pids);
}
}

View File

@@ -145,7 +145,25 @@ class CanStatus(var enabled: Boolean = false): Status() {
*/
class TracingStatus(var state: Tracing = UNKNOWN): Status() {
enum class Tracing(val code: String? = "") {
enum class Tracing(val code: String? = "", var extra: Map<String, String>? = null) {
/**
* 类型切换
*/
MAP_TRA_TYPE("IMAP_TRA_TYPE"),
/**
* 地图数据存在
*/
MAP_DATA_EXIST("IMAP_DATA_EXIST"),
/**
* 地图数据不存在
*/
MAP_DATA_NOT_EXIST("EMAP_DATA_NOT_EXIST"),
/**
* 寻迹-已找到轨迹文件
*/
@@ -182,12 +200,10 @@ class TracingStatus(var state: Tracing = UNKNOWN): Status() {
UNKNOWN;
fun isException(): Boolean {
val c1 = when (this) {
TRACK_FINDED, TRACK_NOT_EXIST, TRACK_LOAD_FAIL, ROUTE_FAILED, UNKNOWN -> true
else -> false
if (this == TRACK_LOADED || this == ROUTE_LOADED) {
return false
}
val c2 = CallerAutoPilotStatusListenerManager.getAutoPilotStatusInfo().state != IMoGoAutopilotStatusListener.STATUS_AUTOPILOT_DISABLE
return c1 and c2
return true
}
}
@@ -212,14 +228,46 @@ class TracingStatus(var state: Tracing = UNKNOWN): Status() {
override fun isException(): Boolean = state.isException()
}
fun String.toState(): Tracing? {
fun String.toState(msg: String?): Tracing? {
val ss = msg?.split("|")
var extra: Map<String, String>? = null
if (ss != null && ss.isNotEmpty()) {
val sb = StringBuilder()
for (element in ss) {
sb.append(element)
sb.append(",")
}
if (sb.isNotEmpty()) {
sb.setLength(sb.length - 1)
}
extra = mutableMapOf("extra" to sb.toString())
}
return when(this) {
"IMAP_TRA_EXIST" -> TRACK_FINDED
"IMAP_TRA_LOADED" -> TRACK_LOADED
"EMAP_TRA_NOT_EXIST" -> TRACK_NOT_EXIST
"EMAP_TRA_LOAD_FAILED" -> TRACK_LOAD_FAIL
"IMAP_TRA_ROUTING" -> ROUTE_LOADED
"IMAP_TRA_EXIST" -> TRACK_FINDED.apply {
this.extra = extra
}
"IMAP_TRA_LOADED" -> TRACK_LOADED.apply {
this.extra = extra
}
"EMAP_TRA_NOT_EXIST" -> TRACK_NOT_EXIST.apply {
this.extra = extra
}
"EMAP_TRA_LOAD_FAILED" -> TRACK_LOAD_FAIL.apply {
this.extra = extra
}
"IMAP_TRA_ROUTING" -> ROUTE_LOADED.apply {
this.extra = extra
}
"EMAP_HADMAP_ENGINE_NO_ROUTING_INFO" -> ROUTE_FAILED
"IMAP_TRA_TYPE" -> MAP_TRA_TYPE.apply {
this.extra = extra
}
"MAP_DATA_EXIST" -> MAP_DATA_EXIST.apply {
this.extra = extra
}
"MAP_DATA_NOT_EXIST" -> MAP_DATA_NOT_EXIST.apply {
this.extra = extra
}
else -> null
}
}

View File

@@ -103,7 +103,7 @@ internal class CanImpl(ctx: Context): IFlow<CanStatus>(ctx), IMoGoAutopilotVehic
private fun timeOutCheck() {
job?.safeCancel()
launch(Dispatchers.Default) {
launch(Dispatchers.Unconfined) {
delay(4000)
send(CanStatus(isCanEnabled()))
}.also { job = it }

View File

@@ -35,21 +35,29 @@ internal class GpsImpl(ctx: Context): IFlow<GpsStatus>(ctx) {
}
private val onClose = {
send(false, PermissionUtils.isGranted(Manifest.permission.ACCESS_FINE_LOCATION))
send(false, isGrandFineLocation())
}
private val onOpen = {
send(true, PermissionUtils.isGranted(Manifest.permission.ACCESS_FINE_LOCATION))
send(true, isGrandFineLocation())
}
private fun isGrandFineLocation(): Boolean = try {
PermissionUtils.isGranted(Manifest.permission.ACCESS_FINE_LOCATION)
} catch (t: Throwable) {
t.printStackTrace()
false
}
override fun onCreate() {
val isGranted = PermissionUtils.isGranted(Manifest.permission.ACCESS_FINE_LOCATION)
val isGranted = isGrandFineLocation()
send(isLocationEnabled(), isGranted)
if (!isGranted) {
PermissionUtils.requestAccessFineLocation(object : SimpleCallback {
override fun onGranted() {
Log.d(TAG,"权限: ${Manifest.permission.ACCESS_FINE_LOCATION} 被授予了....")
send(enabled = isLocationEnabled(), isGranted = false)
send(enabled = isLocationEnabled(), isGranted = true)
}
override fun onDenied() {

View File

@@ -78,12 +78,21 @@ internal class NetsImpl(ctx: Context): IFlow<NetStatus>(ctx) {
private var loopCheckAndSendJob: Job? = null
private fun checkAndSend() {
val connectionInfo = wifiMgr.connectionInfo
val enabled = isNetConnected()
val name = if (isLocationEnabled()) connectionInfo.ssid?.replace(Regex("[\\W]"), "") else "WI-FI"
loopCheckAndSendJob?.safeCancel()
launch(Dispatchers.Default) { delay(1000); checkAndSend() }.also { loopCheckAndSendJob = it }
send(enabled, name)
launch(Dispatchers.Unconfined) {
val connectionInfo = wifiMgr.connectionInfo
val enabled = isNetConnected()
val name =
try {
if (isLocationEnabled()) connectionInfo.ssid?.replace(Regex("[\\W]"), "") else "WI-FI"
} catch (t: Throwable) {
t.printStackTrace()
"WI-FI"
}
send(enabled, name)
delay(1000);
checkAndSend()
}.also { loopCheckAndSendJob = it }
}
private fun isLocationEnabled() =

View File

@@ -44,7 +44,7 @@ internal class RTKImpl(ctx: Context): IFlow<RTKStatus>(ctx), IMoGoAutopilotStatu
return
}
check?.takeIf { it.isActive }?.cancel()
launch {
launch(Dispatchers.Unconfined) {
CallerAutoPilotManager.sendStatusQueryReq()
delay(5000)
isOldVersion.set(true)
@@ -82,7 +82,7 @@ internal class RTKImpl(ctx: Context): IFlow<RTKStatus>(ctx), IMoGoAutopilotStatu
if (isRTKEnabled()) {
send(RTKStatus("RTK", 0))
timeOutCheck?.takeIf { it.isActive }?.cancel()
launch {
launch(Dispatchers.Unconfined) {
delay(4000)
send(RTKStatus("", -1))
}.also {

View File

@@ -1,9 +1,9 @@
package com.zhjt.mogo_core_function_devatools.status.flow.trace
import android.content.*
import android.util.*
import com.mogo.eagle.core.data.autopilot.*
import com.mogo.eagle.core.function.api.autopilot.*
import com.mogo.eagle.core.function.api.autopilot.IMoGoAutopilotStatusListener.Companion.STATUS_AUTOPILOT_RUNNING
import com.mogo.eagle.core.function.call.autopilot.*
import com.zhjt.mogo_core_function_devatools.status.entity.*
import com.zhjt.mogo_core_function_devatools.status.entity.TracingStatus.Tracing.*
@@ -20,7 +20,8 @@ internal class TracingImpl(ctx: Context): IFlow<TracingStatus>(ctx), IMoGoAutopi
override fun onCreate() {
val code = CallerAutoPilotStatusListenerManager.getAutoPilotReportMessageCode()
val state = code.toState() ?: UNKNOWN
val msg = CallerAutoPilotStatusListenerManager.getAutoPilotReportMessageContent()
val state = code.toState(msg) ?: UNKNOWN
old = state
send(TracingStatus(state))
CallerAutoPilotStatusListenerManager.addListener(TAG, this)
@@ -30,7 +31,7 @@ internal class TracingImpl(ctx: Context): IFlow<TracingStatus>(ctx), IMoGoAutopi
override fun onAutopilotGuardian(guardianInfo: MogoReportMessage?) {
super.onAutopilotGuardian(guardianInfo)
val current = guardianInfo?.code
val newState = current?.toState()
val newState = current?.toState(guardianInfo.msg)
if (newState != null && newState != old) {
send(TracingStatus(newState))
old = newState
@@ -40,17 +41,20 @@ internal class TracingImpl(ctx: Context): IFlow<TracingStatus>(ctx), IMoGoAutopi
override fun onAutopilotIpcConnectStatusChanged(status: Int, reason: String?) {
super.onAutopilotIpcConnectStatusChanged(status, reason)
if (!CallerAutoPilotManager.isConnected()) {
old = UNKNOWN
send(TracingStatus(UNKNOWN))
}
}
override fun onAutopilotStatusResponse(autoPilotStatusInfo: AutopilotStatusInfo) {
super.onAutopilotStatusResponse(autoPilotStatusInfo)
if (autoPilotStatusInfo.state == IMoGoAutopilotStatusListener.STATUS_AUTOPILOT_DISABLE) {
if (autoPilotStatusInfo.state != STATUS_AUTOPILOT_RUNNING) {
old = UNKNOWN
send(TracingStatus(UNKNOWN))
return
}
if (old.isException() && autoPilotStatusInfo.state == IMoGoAutopilotStatusListener.STATUS_AUTOPILOT_RUNNING) {
if (old.isException()) {
old = TRACK_LOADED
send(TracingStatus(TRACK_LOADED))
}
}

View File

@@ -6,6 +6,7 @@ import android.widget.*
import androidx.core.content.*
import androidx.recyclerview.widget.*
import com.mogo.eagle.core.utilcode.kotlin.*
import com.mogo.eagle.core.utilcode.mogo.logger.*
import com.mogo.eagle.core.utilcode.util.*
import com.zhjt.mogo_core_function_devatools.*
import com.zhjt.mogo_core_function_devatools.R
@@ -19,6 +20,10 @@ import kotlinx.coroutines.*
internal class StatusAdapter(val ctx: Context, var data: ArrayList<Status>): RecyclerView.Adapter<StatusViewHolder>() {
companion object {
const val TAG = "StatusAdapter"
}
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): StatusViewHolder =
StatusViewHolder(LayoutInflater.from(ctx).inflate(R.layout.layout_status_bar_item, parent, false))
@@ -69,7 +74,7 @@ internal class StatusAdapter(val ctx: Context, var data: ArrayList<Status>): Rec
}
is TracingStatus -> {
when(status.state) {
ROUTE_FAILED, TRACK_LOAD_FAIL, TRACK_NOT_EXIST, TRACK_FINDED, UNKNOWN -> {
MAP_DATA_NOT_EXIST, MAP_DATA_EXIST, MAP_TRA_TYPE, ROUTE_FAILED, TRACK_LOAD_FAIL, TRACK_NOT_EXIST, TRACK_FINDED, UNKNOWN -> {
iv.background = ContextCompat.getDrawable(itemView.context, drawable.icon_dev_status_trace_unkown)
}
TRACK_LOADED -> {
@@ -116,7 +121,26 @@ internal class StatusAdapter(val ctx: Context, var data: ArrayList<Status>): Rec
else ->
"定位异常"
}
is TracingStatus -> "轨迹类型:${ if (status.state == TRACK_LOADED) "循迹" else if (status.state == ROUTE_LOADED) "自主算路" else "暂无轨迹" }"
is TracingStatus -> {
val extra = status.state.extra
val extraDesc = if (extra != null && extra.isNotEmpty()) extra.values.joinToString(",") else ""
Logger.d(TAG, "traceing_state: $status -> extra: $extraDesc :: extra: $extra")
when(status.state) {
//"轨迹类型:${ if (status.state == TRACK_LOADED) "循迹" else if (status.state == ROUTE_LOADED) "自主算路" else "暂无轨迹" }"
MAP_TRA_TYPE -> {
"暂无轨迹"
}
MAP_DATA_EXIST -> "地图数据存在,正在加载${if (extraDesc.isEmpty()) "" else "[$extraDesc]" }"
MAP_DATA_NOT_EXIST -> "地图数据不存在${if (extraDesc.isEmpty()) "" else "[$extraDesc]"}"
TRACK_FINDED -> "轨迹类型:循迹[已找到轨迹$extraDesc]"
TRACK_LOADED -> "轨迹类型:循迹[加载成功$extraDesc]"
TRACK_NOT_EXIST -> "轨迹类型:循迹[不存在$extraDesc]"
TRACK_LOAD_FAIL -> "轨迹类型:循迹[加载失败$extraDesc]"
ROUTE_LOADED -> "轨迹类型:自主算路[加载成功$extraDesc]"
ROUTE_FAILED -> "轨迹类型:自主算路[加载失败$extraDesc]"
UNKNOWN -> "暂无轨迹"
}
}
}
}
}

View File

@@ -57,6 +57,12 @@ class TraceManager : IMoGoCloudListener {
FwBuild(false, 30, pkgName + ChainConstant.CHAIN_LINK_LOG_ADAS_TRAFFIC_LIGHT)
fwBuildMap[ChainConstant.CHAIN_LINK_LOG_WEB_SOCKET_PLANNING_OBJECTS] =
FwBuild(false, 30, pkgName + ChainConstant.CHAIN_LINK_LOG_ADAS_PLANNING_OBJECTS)
fwBuildMap[ChainConstant.CHAIN_LINK_LOG_WEB_SOCKET_PLANNING_ACTIONS] =
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)
traceInfoCache[ChainConstant.CHAIN_LINK_LOG_CONNECT_STATUS] =
ChainLogParam(true, "ADAS连接状态")
@@ -70,8 +76,14 @@ class TraceManager : IMoGoCloudListener {
ChainLogParam(false, "ADAS车前引导线")
traceInfoCache[ChainConstant.CHAIN_LINK_LOG_WEB_SOCKET_VEHICLE] =
ChainLogParam(false, "ADAS车辆底盘数据")
traceInfoCache[ChainConstant.CHAIN_LINK_LOG_WEB_SOCKET_TRAFFIC_LIGHT] =
ChainLogParam(false, "ADAS红绿灯数据")
traceInfoCache[ChainConstant.CHAIN_LINK_LOG_WEB_SOCKET_PLANNING_OBJECTS] =
ChainLogParam(false, "ADAS PLANNING 感知障碍物")
traceInfoCache[ChainConstant.CHAIN_LINK_LOG_WEB_SOCKET_PLANNING_ACTIONS] =
ChainLogParam(true, "ADAS PLANNING 决策行为")
traceInfoCache[ChainConstant.CHAIN_LINK_LOG_NATIVE_LEAK] =
ChainLogParam(true, "Native Leak Record")
FileWriteManager.getInstance()
.init(context, MoGoAiCloudClientConfig.getInstance().sn, pkgName, fwBuildMap)