2.3.0:手表界面精简 + 播放器 + 鼠标重做

手表端
- 功能页从 10 个杂项精简到 7 个(屏幕/鼠标/媒体/文件/电脑/语音/电源)
- 删掉:游戏封锁、待办、掷骰子、抽奖、壁纸、显示器开关、定时关机、
  剪贴板历史、性能/磁盘/电量、文件夹浏览、教室限制等
- 改成显式列按钮,不再把电脑端所有功能组无脑铺到表盘
- 远程鼠标控制重做:滑动区 + 左键/滚轮/右键三按钮
  滚轮点按=中键、上下滑=滚动
- 新增视频/音乐播放器(手表本地播放):进度拖动、左右滑快进退10秒、
  点画面播放暂停、上一/下一、播完自动下一首

电脑端
- 新增 kill_all(结束所有进程),白名单保护系统关键进程和自身
- 新增 media_list / media_pull(播放器数据源)
  安全边界:只允许媒体目录,用 relative_to 判断,防同前缀兄弟目录绕过

中转站
- known_devices 从 ID 集合改成「设备ID -> 配对码」映射
- 修复:管理员改码后关机超过 6 小时,改码会被超时清理冲掉
- 老格式 state 文件平滑升级
This commit is contained in:
xmz7891
2026-10-18 11:39:14 +08:00
parent 1d368979aa
commit 2061f9525f
50 changed files with 13812 additions and 584 deletions
+108
View File
@@ -0,0 +1,108 @@
# -*- coding: utf-8 -*-
"""找出 MainActivity 里**定义了但没人调用**的私有方法。
为什么需要这个:2.3.0 把一半的分页删了,原来那些按钮背后的方法
就全变成孤儿了。一个个跑测试太慢,先用这个脚本一次性列出来。
排除规则(这些"没人调用"是正常的):
* @Override 的回调(框架会调)
* 生命周期方法(onCreate/onPause/...)
* 构造器
* 只有 setVisibility / setText 之类直接操作的不算
"""
from __future__ import annotations
import re
import sys
from pathlib import Path
JAVA = (Path(__file__).resolve().parent.parent
/ "android" / "src" / "com" / "lanremote" / "watch" / "MainActivity.java")
# 框架调用的,不算孤儿
LIFECYCLE = {
"onCreate", "onStart", "onResume", "onPause", "onStop", "onDestroy",
"onActivityResult", "onRequestPermissionsResult", "onBackPressed",
"onNewIntent", "onSaveInstanceState", "onRestoreInstanceState",
"onTouchEvent", "onKeyDown", "onConfigurationChanged",
"onWindowFocusChanged", "onCreateOptionsMenu", "onOptionsItemSelected",
"onClick", "run", "onPrepared", "onCompletion", "onError",
"onProgressChanged", "onStartTrackingTouch", "onStopTrackingTouch",
"onSingleTapConfirmed", "onDoubleTap", "onScroll", "onFling",
"onDown", "onLongPress", "onShowPress", "onSingleTapUp",
"onInput", "onPick", "onResponse", "onFailure", "doInBackground",
"onPostExecute", "beforeTextChanged", "onTextChanged",
"afterTextChanged", "onItemClick", "onItemSelected",
"onNothingSelected", "onFocusChange", "onEditorAction",
}
# 定义方法的各种写法
DEF_RE = re.compile(
r"^[ \t]*(?:@\w+(?:\([^)]*\))?\s*)*"
r"(?:private|protected|public|static|final|synchronized|\s)*"
r"(?:[\w<>\[\],.?\s]+?)\s+(\w+)\s*\([^)]*\)\s*(?:throws [\w,.\s]+)?\s*\{",
re.M)
def main() -> int:
text = JAVA.read_text(encoding="utf-8")
lines = text.split("\n")
# 收集定义(带行号)
defs = []
for i, ln in enumerate(lines):
m = DEF_RE.match(ln)
if not m:
continue
name = m.group(1)
# 排除构造器(名字等于类名)和 exclude 集合
if name in ("MainActivity", "if", "for", "while", "switch", "catch"):
continue
# 排除紧跟在 @Override 后面的
prev = [x.strip() for x in lines[max(0, i - 3):i]]
if any("_override_" == p or "@Override" in p for p in prev):
continue
defs.append((name, i + 1))
# 统计每个名字被调用多少次(排除定义行自己)
def_line = {}
for name, ln in defs:
def_line.setdefault(name, set()).add(ln)
orphans = []
for name, ln in defs:
# 统计调用次数:名字 + "(" 出现次数
occurrences = [(i + 1, l) for i, l in enumerate(lines)
if re.search(r"\b" + re.escape(name) + r"\s*\(", l)]
# 减去定义本身那一行
calls = [o for o in occurrences if o[0] != ln]
# 定义行可能是多行签名的第一行,精确匹配名字出现的所有行
if not calls:
if name not in LIFECYCLE:
orphans.append((name, ln))
print(" 定义的方法 %d 个" % len(defs))
print(" 孤儿方法 %d 个:" % len(orphans))
for name, ln in orphans:
print(" 第 %-5d %s()" % (ln, name))
# 也检查被调用但只出现在注释里的(可能是残留引用)
print()
print(" 被删除后仍被引用的符号(编译错误来源):")
deleted = sys.argv[1:] if len(sys.argv) > 1 else []
for sym in deleted:
hits = [(i + 1, l.strip()) for i, l in enumerate(lines)
if re.search(r"\b" + re.escape(sym) + r"\s*\(", l)]
if hits:
# 判断是不是定义行
deflines = {d[1] for d in defs if d[0] == sym}
real = [h for h in hits if h[0] not in deflines]
if real:
print(" %s: %d 处调用" % (sym, len(real)))
for ln, l in real[:5]:
print(" 第 %d: %s" % (ln, l[:100]))
return 0
if __name__ == "__main__":
sys.exit(main())