import 'package:device_plugin_interface/device_plugin_interface.dart'; import 'bes/bes_device_auth.dart'; import 'bes/bes_device_plugin.dart'; import 'device_hub.dart'; import 'smartcar/smartcar_device_auth.dart'; import 'smartcar/smartcar_device_plugin.dart'; /// 确权结论(厂商无关)。 /// /// ⚠️ [unknown] 的语义是**放行**,不是"失败"。判不出来时放行是刻意选的失败方向: /// 判严的代价是合法用户一断网就用不了自己的设备;判宽只是未登记设备离线时 /// 能用一会儿,联网第一次确权就会被拦下。 enum DeviceAuthResult { /// 白名单命中 / 服务端确认 / 已在 User.devices 里 authorized, /// 服务端明确拒绝(这台 MAC 没登记) denied, /// 未登录 / 断网 / 拿不到 MAC —— **放行** unknown, } /// 设备确权的业务层入口(登出重置、解绑清白名单、补校当前设备)。 /// /// 确权本身是各厂商插件在连接时就地做的(恒玄见 [BesDeviceAuth]),这里只把 /// 需要从业务层触发的几个动作聚在一起,业务层不用知道是哪家的实现。 class DeviceAuth { DeviceAuth._(); /// 登出:换账号后同一台设备要重新登记到新账号名下。**白名单不清**。 static void reset() { BesDeviceAuth.reset(); SmartcarDeviceAuth.reset(); } /// 解绑:移出白名单,下次连上重新走服务端确权。 /// /// 两家都调:调用方只有一个 MAC,不知道它属于哪个厂商, /// 而各家白名单是按 MAC 存的、互不相干,多清一次无副作用。 static Future forget(String mac) async { await BesDeviceAuth.forget(mac); await SmartcarDeviceAuth.forget(mac); } /// 【调试/售后】清空白名单 static Future clearWhitelist() async { await BesDeviceAuth.clearWhitelist(); await SmartcarDeviceAuth.clearWhitelist(); } /// 补校当前连着的、需要确权的设备(顺带完成绑定登记)。 /// 「先连耳机后登录」时连接事件里的登记会因未登录跳过,设备管理页进来补一次。 static Future verifyConnected() async { final hub = DeviceHub.to; for (final s in hub.sessions.toList()) { if (!s.supports(DeviceCapability.macAddress)) continue; final p = hub.plugin(s.vendor); if (p is BesDevicePlugin) { await p.link.auth?.verifyConnected(); } else if (p is SmartcarDevicePlugin) { // Smartcar 的 MAC 来自广播,两端都拿得到(不像恒玄 iOS 只有 UUID) await SmartcarDeviceAuth.verify( mac: s.info.macAddress, name: s.info.name, ); } } } }