Files
ykxmz/_tests/check_layout.py
T
xmz7891 b705216e4a ykxmz 1.5.0锛氫慨澶嶆墜琛ㄧ TLS 璇佷功鏍¢獙 + MTU 淇缃戠粶绋冲畾鎬?
琚帶绔?- 淇 MTU 闂锛氬す MSS + 璺緞 MTU 鎺㈡祴锛堝叕缃戝彲鐢ㄧ巼 48% -> 100%锛?- 澶嶇敤 HTTP 杩炴帴锛堝厤鎺夋瘡娆℃柊寤?TLS 鐨?30% 鎻℃墜澶辫触锛?- 姣忓垎閽熷洖澶存壘灞€鍩熺綉锛岃嚜鍔ㄥ垏鍥炲揩 400 鍊嶇殑璺緞
- 鐢婚潰蹇冭烦甯э細闈欐鏃剁渷娴侀噺锛屽鎴风浠嶇煡閬撴祦鏄椿鐨?- 閿佸睆鏃剁粰鍑哄彲鎿嶄綔鐨勬彁绀?
鎵嬭〃绔?- 鍐呯疆 GTS Root R4 / GlobalSign Root CA锛屼慨 SSLHandshakeException
- 杩炴帴閿欒缈昏瘧鎴愪汉璇濓紙璇佷功/鏃堕棿/瑙f瀽/瓒呮椂鍒嗗埆鎻愮ず锛?- 缁忎腑杞繛涓婂悗鐢ㄦ湇鍔″櫒鎶ョ殑鍦板潃鍒锋柊宸查厤瀵硅褰?- 鏂板灞€鍩熺綉杩炴帴椤甸潰銆佹湇鍔″櫒寤惰繜妫€娴?
鏈嶅姟鍣ㄧ
- 鏀寔 chunked 璇锋眰浣擄紙淇瘡 16 绉掍竴娆$殑杩炴帴閿欎贡涓庡ぇ闈㈢Н 502锛?- 缃戠粶璋冧紭鑴氭湰 net-tune.sh锛堝紑鏈鸿嚜鍔ㄥ簲鐢級
- 绠$悊椤碉細鎵归噺鍒犻櫎銆佺綉缁滀綋妫€銆佷笅杞藉尯
- 闅ч亾鏀?HTTP/2 + 鍙岃繛鎺?
鏂囨。
- 璁稿彲鍗忚 / 瀹夎鍓嶅繀璇?/ 瀹夎鍚庨』鐭ワ紙浣滆€咃細灏忛害瀛愶級
2026-10-06 19:01:05 +08:00

208 lines
8.3 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# -*- coding: utf-8 -*-
"""手表屏幕适配校验。
分两部分:
1. **真机参数**(来自用户实测的诊断报告)—— 这是最该保证的
2. 一组常见 density 的覆盖,防止别的设备上按钮被挤爆
把 MainActivity.adaptGridToScreen() 的布局计算原样搬过来核算。
注意:这是**布局数学核算**,不是真机渲染测试。
没有可用设备/模拟器时,它能提前发现"screensize 一变按钮就挤爆"这类问题。
"""
from __future__ import annotations
import sys
PANEL_PADDING_DP = 8.0 # controlPanel 左右 padding
CELL_MARGIN_DP = 3.0 # 每个按钮的外边距
BUTTON_PADDING_DP = 4.0 # 按钮内部左右 padding
MIN_TOUCH_DP = 48.0 # Android 无障碍最小点击高度
# 现在手表端分 6 页,每页按钮数不一样。
# 关键指标变成「每一页都能一屏放下、不用滚动」。
# 现在分 10 页:功能页已删除,14 个分组散到各页。
# 括号里只统计**固定快捷按钮**;功能分组是滚动区,会显示在下面。
# 现在分 10 页:功能页已删除,14 个分组散到各页。
# 括号里只统计**固定快捷按钮**;功能分组是滚动区,会显示在下面。
# 每页最多 3 行(9 个),超了会滚动。
TABS = {
"媒体": ["播放/暂停", "停止", "上一曲", "下一曲", "音量 +", "音量 -", "静音"],
"屏幕": ["关掉画面", "屏幕镜像", "截屏", "投图到电脑", "放音到电脑"],
"文件": ["发送文件", "接收文件", "剪贴板→电脑", "取电脑剪贴板"],
"语音": ["语音播报", "音色", "朗读剪贴板", "电脑音乐", "弹通知"],
"电脑": ["快捷命令", "打开网址", "进程管理", "性能", "磁盘", "电量"],
"网络": ["本机监听端口", "确认能连上"],
"系统": ["回退上一步", "回退全部", "看能回退什么",
"锁屏", "睡眠", "关机", "重启", "取消定时关机", "定时关机"],
"教室": ["屏蔽游戏网站", "结束游戏进程", "一键恢复全部", "看有哪些限制"],
"效率": ["加待办", "看所有待办"],
"娱乐": ["掷骰子", "抽奖", "抛硬币"],
}
# 每页还挂着哪些功能分组(这些在滚动区里)
TAB_GROUPS = {
"媒体": ["音量", "媒体"],
"屏幕": ["显示"],
"文件": ["文件"],
"语音": ["静默"],
"电脑": ["查看", "工具"],
"网络": ["网络", "极客"],
"系统": ["系统"],
"教室": ["教室", "教学"],
"效率": ["效率"],
"娱乐": ["娱乐"],
}
LABELS = [label for group in TABS.values() for label in group]
# 用户实测的设备(来自遥控诊断报告)
REAL_DEVICE = {
"name": "M60T (hesc, Android 9 / API 28)",
"width_px": 492,
"height_px": 602,
"density": 1.4125,
"density_dpi": 226,
}
PASSED = 0
FAILED = 0
def check(name: str, ok: bool, detail: str = "") -> None:
global PASSED, FAILED
if ok:
PASSED += 1
print(f" [PASS] {name}")
else:
FAILED += 1
print(f" [FAIL] {name} {detail}")
def adapt(width_dp: float, height_dp: float):
"""与 Java 端 adaptGridToScreen() 一致。"""
if width_dp < 200:
return 1, 64.0, 16.0
if width_dp < 300:
columns, height, text = 2, 60.0, 14.0
elif width_dp < 330:
columns, height, text = 2, 64.0, 15.0
else:
columns, height, text = 3, 58.0, 13.0
if height_dp < 320 and columns == 2:
height = 56.0
return columns, height, text
def label_width_dp(label: str, text_sp: float) -> float:
"""估算文字宽度:中日韩字符约 1em,其余约 0.55em。"""
total = 0.0
for ch in label:
total += 1.0 if ord(ch) > 0x2E80 else 0.55
return total * text_sp
def report_one(tag: str, width_px: float, height_px: float, density: float) -> float:
"""核算一台设备,返回最紧的文字余量。"""
width_dp = width_px / density
height_dp = height_px / density
columns, cell_h, text_sp = adapt(width_dp, height_dp)
content_dp = width_dp - PANEL_PADDING_DP * 2
# 每行 columns 个按钮,每个按钮左右各一个 3dp 外边距
cell_w = (content_dp - CELL_MARGIN_DP * 2 * columns) / columns
text_area = cell_w - BUTTON_PADDING_DP * 2
print(f"\n{tag}")
print(f" {width_px:.0f}x{height_px:.0f}px density={density} -> "
f"{width_dp:.0f}x{height_dp:.0f} dp")
print(f" 列数={columns} 按钮高={cell_h:.0f}dp 字号={text_sp:.0f}sp "
f"按钮宽={cell_w:.1f}dp 可用文字宽={text_area:.1f}dp")
check(f"{tag} 按钮高度 >= {MIN_TOUCH_DP:.0f}dp", cell_h >= MIN_TOUCH_DP,
f"实际 {cell_h}dp")
longest = max(LABELS, key=lambda s: label_width_dp(s, text_sp))
need = label_width_dp(longest, text_sp)
lines = 1 if need <= text_area else 2
needed_h = lines * text_sp * 1.3 + 6
check(f"{tag} 最长文字「{longest}」放得下", needed_h <= cell_h,
f"需 {need:.0f}dp 宽 / {needed_h:.0f}dp 高,可用 {text_area:.0f}dp / {cell_h:.0f}dp")
print(f" 「{longest}」{need:.1f}dp -> {lines} 行,需高 {needed_h:.1f}dp")
margin = text_area / need
check(f"{tag} 文字余量 >= 95%", margin >= 0.95, f"余量 {margin * 100:.0f}%")
print(f" 文字余量 {margin * 100:.0f}%")
rows = (len(LABELS) + columns - 1) // columns
scroll_dp = rows * (cell_h + CELL_MARGIN_DP * 2)
print(f" 按钮 {len(LABELS)} 个 -> {rows} 行,总高约 {scroll_dp:.0f}dp"
f"(屏高 {height_dp:.0f}dp,需滚动 {max(0, scroll_dp - height_dp + 60):.0f}dp)")
return margin
def main() -> int:
print("=" * 74)
print("一、真机参数(来自用户实测的遥控诊断报告)")
print("=" * 74)
dev = REAL_DEVICE
report_one(f"实测设备: {dev['name']}", dev["width_px"], dev["height_px"],
dev["density"])
# ---- 分页:每页都要能一屏放下 ----
print()
print("=" * 74)
print("三、分页布局(每页不超过 7 个按钮)")
print("=" * 74)
width_dp = dev["width_px"] / dev["density"]
height_dp = dev["height_px"] / dev["density"]
columns, cell_h, text_sp = adapt(width_dp, height_dp)
# 顶栏 42dp + 标签栏 42dp + 日志约 60dp + 边距
chrome_dp = 42 + 42 + 62 + 20
available = height_dp - chrome_dp
for name, labels in TABS.items():
rows = (len(labels) + columns - 1) // columns
need = rows * (cell_h + 6)
fits = need <= available
check(f"「{name}」{len(labels)} 个按钮 / {rows} 行,一屏放得下",
fits, f"需要 {need:.0f}dp,可用 {available:.0f}dp")
print(f" {name}: {len(labels)} 个 / {rows} 行 / {need:.0f}dp"
f"(可用 {available:.0f}dp)")
real_cols = adapt(dev["width_px"] / dev["density"], dev["height_px"] / dev["density"])[0]
check(f"真机走 {real_cols} 列布局(348dp 宽应走三列以减少滚动)", real_cols == 3,
f"实际 {real_cols} 列")
# 报告里的 densityDpi 与 density 换算是否自洽
implied = dev["density"] * 160
check(f"density 与 densityDpi 自洽({dev['density']} x 160 = {implied:.0f},"
f"报告值 {dev['density_dpi']})",
abs(implied - dev["density_dpi"]) <= 2,
f"差 {abs(implied - dev['density_dpi']):.1f}")
print("\n" + "=" * 74)
print("二、同一分辨率下不同 density 的覆盖")
print("=" * 74)
worst = 1e9
two_col = 0
for density in [1.0, 1.25, 1.4125, 1.5, 1.75, 2.0, 2.5, 3.0]:
margin = report_one(f"density={density}",
dev["width_px"], dev["height_px"], density)
worst = min(worst, margin)
if adapt(dev["width_px"] / density, dev["height_px"] / density)[0] >= 2:
two_col += 1
print("\n" + "=" * 74)
print(f"最紧的一档文字余量: {worst * 100:.0f}%")
check("常见 density 下不会退化成单列", two_col >= 6,
f"多列档数 {two_col}")
print("\n" + "=" * 74)
print(f"通过 {PASSED} 项,失败 {FAILED} 项")
return 1 if FAILED else 0
if __name__ == "__main__":
sys.exit(main())