mirror of
https://github.com/gkd-kit/gkd.git
synced 2024-11-16 11:42:22 +08:00
refactor: http server, snapshot
This commit is contained in:
parent
978552b4b2
commit
59ad7b7355
|
@ -21,6 +21,10 @@ data class AppInfo(
|
|||
val hidden: Boolean,
|
||||
)
|
||||
|
||||
val selfAppInfo by lazy {
|
||||
app.packageManager.getPackageInfo(app.packageName, 0).toAppInfo()!!
|
||||
}
|
||||
|
||||
/**
|
||||
* 平均单次调用时间 11ms
|
||||
*/
|
||||
|
|
|
@ -6,7 +6,7 @@ interface BaseSnapshot {
|
|||
val appId: String?
|
||||
val activityId: String?
|
||||
val appName: String?
|
||||
val appVersionCode: Int?
|
||||
val appVersionCode: Long?
|
||||
val appVersionName: String?
|
||||
|
||||
val screenHeight: Int
|
||||
|
|
|
@ -1,9 +1,8 @@
|
|||
package li.songe.gkd.data
|
||||
|
||||
import com.blankj.utilcode.util.AppUtils
|
||||
import com.blankj.utilcode.util.ScreenUtils
|
||||
import kotlinx.serialization.Serializable
|
||||
import li.songe.gkd.BuildConfig
|
||||
import li.songe.gkd.app
|
||||
import li.songe.gkd.service.GkdAbService
|
||||
import li.songe.gkd.service.getAndUpdateCurrentRules
|
||||
import li.songe.gkd.service.safeActiveWindow
|
||||
|
@ -14,18 +13,22 @@ data class ComplexSnapshot(
|
|||
|
||||
override val appId: String?,
|
||||
override val activityId: String?,
|
||||
override val appName: String?,
|
||||
override val appVersionCode: Int?,
|
||||
override val appVersionName: String?,
|
||||
|
||||
override val screenHeight: Int,
|
||||
override val screenWidth: Int,
|
||||
override val isLandscape: Boolean,
|
||||
|
||||
val gkdVersionCode: Int = BuildConfig.VERSION_CODE,
|
||||
val gkdVersionName: String = BuildConfig.VERSION_NAME,
|
||||
val appInfo: AppInfo? = appId?.let { app.packageManager.getPackageInfo(appId, 0)?.toAppInfo() },
|
||||
val gkdAppInfo: AppInfo? = selfAppInfo,
|
||||
val device: DeviceInfo = DeviceInfo.instance,
|
||||
|
||||
@Deprecated("use appInfo")
|
||||
override val appName: String? = appInfo?.name,
|
||||
@Deprecated("use appInfo")
|
||||
override val appVersionCode: Long? = appInfo?.versionCode,
|
||||
@Deprecated("use appInfo")
|
||||
override val appVersionName: String? = appInfo?.versionName,
|
||||
|
||||
val device: DeviceInfo,
|
||||
val nodes: List<NodeInfo>,
|
||||
) : BaseSnapshot
|
||||
|
||||
|
@ -34,21 +37,17 @@ fun createComplexSnapshot(): ComplexSnapshot {
|
|||
val currentAbNode = GkdAbService.service?.safeActiveWindow
|
||||
val appId = currentAbNode?.packageName?.toString()
|
||||
val currentActivityId = getAndUpdateCurrentRules().topActivity.activityId
|
||||
val appInfo = if (appId == null) null else AppUtils.getAppInfo(appId)
|
||||
|
||||
return ComplexSnapshot(
|
||||
id = System.currentTimeMillis(),
|
||||
|
||||
appId = appId,
|
||||
activityId = currentActivityId,
|
||||
appName = appInfo?.name,
|
||||
appVersionCode = appInfo?.versionCode,
|
||||
appVersionName = appInfo?.versionName,
|
||||
|
||||
screenHeight = ScreenUtils.getScreenHeight(),
|
||||
screenWidth = ScreenUtils.getScreenWidth(),
|
||||
isLandscape = ScreenUtils.isLandscape(),
|
||||
device = DeviceInfo.instance,
|
||||
|
||||
nodes = NodeInfo.info2nodeList(currentAbNode)
|
||||
)
|
||||
}
|
||||
|
@ -59,13 +58,14 @@ fun ComplexSnapshot.toSnapshot(): Snapshot {
|
|||
|
||||
appId = appId,
|
||||
activityId = activityId,
|
||||
appName = appName,
|
||||
appVersionCode = appVersionCode,
|
||||
appVersionName = appVersionName,
|
||||
|
||||
screenHeight = screenHeight,
|
||||
screenWidth = screenWidth,
|
||||
isLandscape = isLandscape,
|
||||
|
||||
appName = appInfo?.name,
|
||||
appVersionCode = appInfo?.versionCode,
|
||||
appVersionName = appInfo?.versionName,
|
||||
)
|
||||
}
|
||||
|
||||
|
|
|
@ -2,7 +2,6 @@ package li.songe.gkd.data
|
|||
|
||||
import android.os.Build
|
||||
import kotlinx.serialization.Serializable
|
||||
import li.songe.gkd.BuildConfig
|
||||
|
||||
@Serializable
|
||||
data class DeviceInfo(
|
||||
|
@ -12,8 +11,6 @@ data class DeviceInfo(
|
|||
val brand: String,
|
||||
val sdkInt: Int,
|
||||
val release: String,
|
||||
val gkdVersionCode: Int,
|
||||
val gkdVersionName: String
|
||||
) {
|
||||
companion object {
|
||||
val instance by lazy {
|
||||
|
@ -24,8 +21,6 @@ data class DeviceInfo(
|
|||
brand = Build.BRAND,
|
||||
sdkInt = Build.VERSION.SDK_INT,
|
||||
release = Build.VERSION.RELEASE,
|
||||
gkdVersionCode = BuildConfig.VERSION_CODE,
|
||||
gkdVersionName = BuildConfig.VERSION_NAME,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -7,4 +7,5 @@ import kotlinx.serialization.Serializable
|
|||
data class RpcError(
|
||||
override val message: String,
|
||||
@SerialName("__error") val error: Boolean = true,
|
||||
val unknown: Boolean = false,
|
||||
) : Exception(message)
|
||||
|
|
|
@ -25,7 +25,7 @@ data class Snapshot(
|
|||
@ColumnInfo(name = "app_id") override val appId: String?,
|
||||
@ColumnInfo(name = "activity_id") override val activityId: String?,
|
||||
@ColumnInfo(name = "app_name") override val appName: String?,
|
||||
@ColumnInfo(name = "app_version_code") override val appVersionCode: Int?,
|
||||
@ColumnInfo(name = "app_version_code") override val appVersionCode: Long?,
|
||||
@ColumnInfo(name = "app_version_name") override val appVersionName: String?,
|
||||
|
||||
@ColumnInfo(name = "screen_height") override val screenHeight: Int,
|
||||
|
|
|
@ -30,12 +30,14 @@ import kotlinx.serialization.Serializable
|
|||
import li.songe.gkd.app
|
||||
import li.songe.gkd.appScope
|
||||
import li.songe.gkd.composition.CompositionService
|
||||
import li.songe.gkd.data.AppInfo
|
||||
import li.songe.gkd.data.DeviceInfo
|
||||
import li.songe.gkd.data.GkdAction
|
||||
import li.songe.gkd.data.RawSubscription
|
||||
import li.songe.gkd.data.RpcError
|
||||
import li.songe.gkd.data.SubsItem
|
||||
import li.songe.gkd.data.deleteSubscription
|
||||
import li.songe.gkd.data.selfAppInfo
|
||||
import li.songe.gkd.db.DbSet
|
||||
import li.songe.gkd.debug.SnapshotExt.captureSnapshot
|
||||
import li.songe.gkd.notif.createNotif
|
||||
|
@ -74,7 +76,12 @@ class HttpService : CompositionService({
|
|||
routing {
|
||||
get("/") { call.respondText(ContentType.Text.Html) { "<script type='module' src='$SERVER_SCRIPT_URL'></script>" } }
|
||||
route("/api") {
|
||||
// Deprecated
|
||||
get("/device") { call.respond(DeviceInfo.instance) }
|
||||
|
||||
post("/getServerInfo") { call.respond(ServerInfo()) }
|
||||
|
||||
// Deprecated
|
||||
get("/snapshot") {
|
||||
val id = call.request.queryParameters["id"]?.toLongOrNull()
|
||||
?: throw RpcError("miss id")
|
||||
|
@ -84,6 +91,16 @@ class HttpService : CompositionService({
|
|||
}
|
||||
call.respondFile(fp)
|
||||
}
|
||||
post("/getSnapshot") {
|
||||
val data = call.receive<ReqId>()
|
||||
val fp = File(SnapshotExt.getSnapshotPath(data.id))
|
||||
if (!fp.exists()) {
|
||||
throw RpcError("对应快照不存在")
|
||||
}
|
||||
call.respond(fp)
|
||||
}
|
||||
|
||||
// Deprecated
|
||||
get("/screenshot") {
|
||||
val id = call.request.queryParameters["id"]?.toLongOrNull()
|
||||
?: throw RpcError("miss id")
|
||||
|
@ -93,12 +110,31 @@ class HttpService : CompositionService({
|
|||
}
|
||||
call.respondFile(fp)
|
||||
}
|
||||
post("/getScreenshot") {
|
||||
val data = call.receive<ReqId>()
|
||||
val fp = File(SnapshotExt.getScreenshotPath(data.id))
|
||||
if (!fp.exists()) {
|
||||
throw RpcError("对应截图不存在")
|
||||
}
|
||||
call.respondFile(fp)
|
||||
}
|
||||
|
||||
// Deprecated
|
||||
get("/captureSnapshot") {
|
||||
call.respond(captureSnapshot())
|
||||
}
|
||||
post("/captureSnapshot") {
|
||||
call.respond(captureSnapshot())
|
||||
}
|
||||
|
||||
// Deprecated
|
||||
get("/snapshots") {
|
||||
call.respond(DbSet.snapshotDao.query().first())
|
||||
}
|
||||
post("/getSnapshots") {
|
||||
call.respond(DbSet.snapshotDao.query().first())
|
||||
}
|
||||
|
||||
post("/updateSubscription") {
|
||||
val subscription =
|
||||
RawSubscription.parse(call.receiveText(), json5 = false)
|
||||
|
@ -108,13 +144,9 @@ class HttpService : CompositionService({
|
|||
version = 0,
|
||||
author = "@gkd-kit/inspect"
|
||||
)
|
||||
try {
|
||||
updateSubscription(subscription)
|
||||
DbSet.subsItemDao.insert((subsItemsFlow.value.find { s -> s.id == httpSubsItem.id }
|
||||
?: httpSubsItem).copy(mtime = System.currentTimeMillis()))
|
||||
} catch (e: Exception) {
|
||||
throw RpcError(e.message ?: "未知")
|
||||
}
|
||||
updateSubscription(subscription)
|
||||
DbSet.subsItemDao.insert((subsItemsFlow.value.find { s -> s.id == httpSubsItem.id }
|
||||
?: httpSubsItem).copy(mtime = System.currentTimeMillis()))
|
||||
call.respond(RpcOk())
|
||||
}
|
||||
post("/execSelector") {
|
||||
|
@ -190,6 +222,17 @@ data class RpcOk(
|
|||
val message: String? = null,
|
||||
)
|
||||
|
||||
@Serializable
|
||||
data class ReqId(
|
||||
val id: Long,
|
||||
)
|
||||
|
||||
@Serializable
|
||||
data class ServerInfo(
|
||||
val device: DeviceInfo = DeviceInfo.instance,
|
||||
val gkdAppInfo: AppInfo = selfAppInfo
|
||||
)
|
||||
|
||||
fun clearHttpSubs() {
|
||||
// 如果 app 被直接在任务列表划掉, HTTP订阅会没有清除, 所以在后续的第一次启动时清除
|
||||
if (HttpService.isRunning.value) return
|
||||
|
|
|
@ -2,7 +2,6 @@ package li.songe.gkd.debug
|
|||
|
||||
import android.util.Log
|
||||
import com.blankj.utilcode.util.LogUtils
|
||||
import io.ktor.http.HttpStatusCode
|
||||
import io.ktor.server.application.createApplicationPlugin
|
||||
import io.ktor.server.application.hooks.CallFailed
|
||||
import io.ktor.server.plugins.origin
|
||||
|
@ -29,7 +28,7 @@ val KtorErrorPlugin = createApplicationPlugin(name = "KtorErrorPlugin") {
|
|||
// 未知错误
|
||||
LogUtils.d(call.request.uri, cause.message)
|
||||
cause.printStackTrace()
|
||||
call.respond(HttpStatusCode.InternalServerError, cause)
|
||||
call.respond(RpcError(message = cause.message ?: "unknown error", unknown = true))
|
||||
}
|
||||
|
||||
else -> {
|
||||
|
|
Loading…
Reference in New Issue
Block a user