小米手机 Notion 密钥登录失败分析 Notion App 通行密钥(Passkey)登录卡死排查分析报告 1. 现象描述 完成 credentialservice 的底层配置并重启手机后: Chrome 浏览器: 访问通行密钥测试站(如 passkeys.io),能正常唤起系统底栏与指纹验证,秒级完成 Passkey 登录。 Notion App: 点击“使用通行密钥登录”后,界面无任何系统弹窗,持续转圈,最终静默失败或提示超时。 --- 2. 日志抓取与根因定位 通过终端监控实时日志: adb logcat -s CredentialManager Fido CredManController 在 Notion 点击登录的瞬间,捕获到核心阻断日志: CredentialManager: starting executeGetCredential with callingPackage: notion.id ... CredentialManager: Remote provider responded with a valid response: ComponentInfo{com.google.android.gms/...RemoteService} CredentialManager: Remote entry being dropped as it is not from the service configured by the OEM. CredentialManager: Remote entry being dropped as it does not meet the restriction checks. ... CredentialManager: Client binder died - clearing session 根因深度剖析 1. 调用通道分化: Chrome(本地通道): Chrome 拥有独立通道,直接与 Google Play 服务的本地 FIDO 认证组件(PasswordAndPasskeyService / AuthenticationActivity)通讯,完全避开了系统的跨进程 OEM 过滤器。 Notion App(标准远程通道): Notion 按照 Android 标准的 androidx.credentials 规范向系统进程(systemserver)请求凭据。系统判定其为外部跨设备请求,并唤起 GMS 的 RemoteService。 2. 小米 OEM 校验逻辑拦截: 在向 Notion 返回数据之前,系统的 CredentialManagerServiceImpl 强制校验了服务来源是否属于编译时指定的 OEM 服务。因 GMS 远程凭据未通过该 OEM 校验,数据被系统底层静默丢弃(Dropped)。 3. 死锁与超时: 数据被底层丢弃后,系统未向 Notion 抛出失败异常,Notion 无法捕获任何结果导致持续转圈,直至 Binder 会话超时强制断连(Client binder died)。 --- 3. 测试与结论 ADB 外部配置无效 后续尝试通过 ADB 写入 credentialserviceprimary 并调整 deviceconfig(禁用 OEM 覆盖策略),日志证实拦截依然原样触发: W CredentialManager: Remote entry being dropped as it is not from the service configured by the OEM. 结论 该 OEM 限制并非独立 APK 软件行为,而是写死在系统核心框架(services.jar 内的 CredentialManagerServiceImpl)中,读取的是静态编译于 framework-res.apk 的白名单配置。免 Root 状态下无法通过 ADB、卸载应用或修改系统属性来解除该限制。 --- 4. 应对与解决方案 方案 A:浏览器中转(免 Root 推荐) 1. 在手机端使用 Chrome 浏览器 打开 www.notion.so。 2. 在网页端完成通行密钥(Passkey)登录。 3. 登录后通过网页提示或页面设置点击 “在应用中打开”(Open in Notion App),无缝继承登录状态回客户端。 方案 B:传统凭据登录(免 Root) 在 Notion 登录界面选择使用常规密码或“邮箱临时登录码(Magic Link)”完成身份验证,绕过底层 Passkey 接口。 方案 C:框架层 Hook(需 Root) 在已解锁 BL 并配置 Magisk / KernelSU + LSPosed 的环境下: 借助针对小米系统的模块(如 Cemiuiler / 核心破解)。 动态 Hook CredentialManagerServiceImpl 中的 isFromConfiguredServiceLocked 方法,强行返回 true,彻底移除 OEM 远程丢弃限制。