在平常首次使用手机进行adb相关调试时候,我们都需要先打开开发者选项,然后去打开USB debuging开关。

上面开关打开后,一般第一次会有个弹框让用户确认权益

接下来就可以通过adb shell进行使用了

大家是否有思考过“为啥在开发者选项中这个开关一开,电脑就可以使用adb”? 下面我们来详细分析整个过程。
本文基于当前 AOSP 源码(Android 13),梳理从开发者选项里的 USB 调试(ADB) 开关被点击,到主机执行 adb devices 能识别设备这条完整链路。
1. 整体调用链概览
Settings 开发者选项 enable_adb 开关 │ ▼AbstractEnableAdbPreferenceController.handlePreferenceTreeClick() │ (首次开启弹 EnableAdbWarningDialog 确认) ▼writeAdbSetting(true) → Settings.Global.ADB_ENABLED = 1 │ ▼ (ContentObserver)AdbService.AdbSettingsObserver │ ▼AdbService.setAdbEnabled(enable, AdbTransportType.USB) │ ├─ startAdbd(): SystemProperties.set("ctl.start", "adbd") │ ├─ AdbDebuggingManager.setAdbEnabled(enable, USB) // 鉴权/授权 │ └─ IAdbTransport.onAdbEnabled() → UsbDeviceManager // USB function │ ▼ 写 persist.sys.usb.config 加入 adb → sys.usb.config 触发 init │ ▼ init.usb.rc / init.usb.configfs.rc 启动 adbd 并重配 USB gadget │ ▼ adbd RSA 鉴权 → 主机 adb devices 显示 device核心解耦不变:Settings UI 只写一个 Settings.Global 配置项,真正干活的是 system_server 里的内容观察者与各系统服务。
2. Settings 层:点击开关只写一个全局设置
2.1 Preference 定义
文件:packages/apps/Settings/res/xml/development_settings.xml(第 135–138 行)
<com.android.settingslib.RestrictedSwitchPreferenceandroid:key="enable_adb"android:title="@string/enable_adb"android:summary="@string/enable_adb_summary" />注意 key 是 enable_adb,控件类型为 RestrictedSwitchPreference(可被 admin 禁用)。
2.2 Controller 处理点击
AdbPreferenceController 本身很薄,真正的点击处理逻辑在 settingslib 的父类里。
packages/apps/Settings/src/com/android/settings/development/AdbPreferenceController.java父类 frameworks/base/packages/SettingsLib/src/com/android/settingslib/development/AbstractEnableAdbPreferenceController.java
父类关键逻辑:
// KEY_ENABLE_ADB = "enable_adb"@OverridepublicbooleanhandlePreferenceTreeClick(Preference preference){if (TextUtils.equals(KEY_ENABLE_ADB, preference.getKey())) {if (!isAdbEnabled()) { showConfirmationDialog(preference); // 首次开启先弹警告框 } else { writeAdbSetting(false); // 关闭:直接写 0 }returntrue; }returnfalse;}protectedvoidwriteAdbSetting(boolean enabled){ Settings.Global.putInt(mContext.getContentResolver(), Settings.Global.ADB_ENABLED, enabled ? 1 : 0); notifyStateChanged(); // 发 ACTION_ENABLE_ADB_STATE_CHANGED 本地广播}2.3 首次开启的确认对话框
AdbPreferenceController.showConfirmationDialog() 弹出 EnableAdbWarningDialog;用户在对话框点“确定”后,DevelopmentSettingsDashboardFragment.onEnableAdbDialogConfirmed() 回调 controller.onAdbDialogConfirmed() → writeAdbSetting(true)。
2.4 其他约束
isAvailable()仅isAdminUser()为 true(仅主用户可用)。updateState()会通过checkIfUsbDataSignalingIsDisabled()判断是否被 admin 禁用 USB 数据信号。
结论:Settings 侧点击开关最终只做一件事——写 Settings.Global.ADB_ENABLED(常量定义在 frameworks/base/core/java/android/provider/Settings.java,Global.ADB_ENABLED = "adb_enabled")。
3. 系统服务层:谁在监听 ADB_ENABLED
AdbService 在构造时注册 AdbSettingsObserver,同时监听两个 URI:
Settings.Global.ADB_ENABLED | |
Settings.Global.ADB_WIFI_ENABLED |
文件:frameworks/base/services/core/java/com/android/server/adb/AdbService.java
privateclassAdbSettingsObserverextendsContentObserver{@OverridepublicvoidonChange(boolean selfChange, Uri uri, int userId){if (mAdbUsbUri.equals(uri)) {boolean shouldEnable = Settings.Global.getInt( mContentResolver, Settings.Global.ADB_ENABLED, 0) > 0;// 派发到 FgThread 执行 setAdbEnabled(shouldEnable, USB) } elseif (mAdbWifiUri.equals(uri)) {// 类似,transportType = WIFI } }}AdbService.setAdbEnabled(enable, transportType)(约 502 行)做三件事:
startAdbd()/stopAdbd()通知所有注册的 IAdbTransport(其中就有UsbDeviceManager)mDebuggingManager.setAdbEnabled(enable, transportType)管理鉴权
startAdbd() / stopAdbd()(约 479–487 行):
privatevoidstartAdbd(){ SystemProperties.set(CTL_START, ADBD); // ctl.start = "adbd"}privatevoidstopAdbd(){if (!mIsAdbUsbEnabled && !mIsAdbWifiEnabled) { SystemProperties.set(CTL_STOP, ADBD); // ctl.stop = "adbd" }}这里直接写
ctl.start/ctl.stop属性,并且 USB 与 WiFi 任一开启都会保持 adbd 运行,两者都关闭时才停止 adbd。
4. AdbDebuggingManager:鉴权与授权
文件:frameworks/base/services/core/java/com/android/server/adb/AdbDebuggingManager.java
publicvoidsetAdbEnabled(boolean enabled, byte transportType){if (transportType == AdbTransportType.USB) { mHandler.sendEmptyMessage(enabled ? MESSAGE_ADB_ENABLED : MESSAGE_ADB_DISABLED); } elseif (transportType == AdbTransportType.WIFI) { mHandler.sendEmptyMessage(enabled ? MSG_ADBDWIFI_ENABLE : MSG_ADBDWIFI_DISABLE); }}它通过 Handler 消息维护 ADB 授权状态:管理 /data/misc/adb/adb_keys(已授权公钥)、临时授权、授权弹窗 UI(“允许 USB 调试吗?”)等。
5. UsbDeviceManager:更新 USB function
UsbDeviceManager 通过内部类 AdbTransport 实现 IAdbTransport,被 AdbService 回调:
文件:frameworks/base/services/usb/java/com/android/server/usb/UsbDeviceManager.java
privatestaticclassAdbTransportextendsIAdbTransport.Stub{@OverridepublicvoidonAdbEnabled(boolean enabled, byte transportType){if (transportType == AdbTransportType.USB) { mHandler.sendMessage(MSG_ENABLE_ADB, enabled); } }}Handler 收到 MSG_ENABLE_ADB 后调用 setAdbEnabled(enable)(约 679 行):
privatevoidsetAdbEnabled(boolean enable){if (enable) { setSystemProperty(USB_PERSISTENT_CONFIG_PROPERTY, UsbManager.USB_FUNCTION_ADB); } else { setSystemProperty(USB_PERSISTENT_CONFIG_PROPERTY, ""); } setEnabledFunctions(mCurrentFunctions, true); updateAdbNotification(false);}其中 USB_PERSISTENT_CONFIG_PROPERTY = "persist.sys.usb.config"。setEnabledFunctions() 最终把 adb function 写入内核 USB gadget(传统 android_usb 接口走 /sys/class/android_usb/...,configfs 走 /config/usb_gadget/g1/...),并触发 sys.usb.config 属性变化。
6. init 启动 adbd
当前 adbd 的启停由两条路径共同完成:
ctl.start=adbd/ctl.stop=adbd:由AdbService直接写属性触发 init 启停进程。sys.usb.config变化:由 USB function 配置触发 init 重配 gadget,并附带start adbd/stop adbd。
文件:system/core/rootdir/init.usb.rc(传统 android_usb)
service adbd /system/bin/adbd --root_seclabel=u:r:su:s0 class core socket adbd seqpacket 660 system system disabled updatable seclabel u:r:adbd:s0on property:sys.usb.config=adb && property:sys.usb.configfs=0 write /sys/class/android_usb/android0/functions ${sys.usb.config} ... start adbd setprop sys.usb.state ${sys.usb.config}文件:system/core/rootdir/init.usb.configfs.rc(configfs)
on property:sys.usb.config=mtp,adb && property:sys.usb.configfs=1 start adbdon property:sys.usb.ffs.ready=1 && property:sys.usb.config=mtp,adb && property:sys.usb.configfs=1 symlink /config/usb_gadget/g1/functions/ffs.adb /config/usb_gadget/g1/configs/b.1/f2 write /config/usb_gadget/g1/UDC ${sys.usb.controller} setprop sys.usb.state ${sys.usb.config}7. adbd 鉴权:从 unauthorized 到 device
即使 adbd 运行,adb devices 也不一定直接是 device:
offline | |
unauthorized | |
device |
当 ro.adb.secure = 1 时,主机公钥由 AdbDebuggingManager 处理:不在 /data/misc/adb/adb_keys 中则弹授权框,用户允许后写入并回传确认,状态变为 device。
8. 完整时序总结
开启(首次)
用户点击 enable_adb开关。AbstractEnableAdbPreferenceController.handlePreferenceTreeClick()弹出EnableAdbWarningDialog。用户确认 → onEnableAdbDialogConfirmed()→writeAdbSetting(true)→Settings.Global.ADB_ENABLED = 1。AdbService.AdbSettingsObserver收到变化 →setAdbEnabled(true, USB)。startAdbd()写ctl.start=adbd,adbd 启动。回调 IAdbTransport.onAdbEnabled()→UsbDeviceManager.setAdbEnabled(true)写persist.sys.usb.config加入adb,并触发sys.usb.config变化。init 重配 USB gadget,绑定 adbfunction,设备重新枚举。AdbDebuggingManager处理 RSA 鉴权,主机adb devices先unauthorized,授权后变device。
关闭
handlePreferenceTreeClick()直接writeAdbSetting(false)→ADB_ENABLED = 0。AdbService.setAdbEnabled(false, USB)→ 若 WiFi 也未开启则ctl.stop=adbd。UsbDeviceManager从persist.sys.usb.config移除adb,USB gadget 重配,主机失去 ADB 接口。
9. 关键源码文件清单
packages/apps/Settings/res/xml/development_settings.xml | enable_adb 开关 |
packages/apps/Settings/src/com/android/settings/development/AdbPreferenceController.java | |
frameworks/base/packages/SettingsLib/src/com/android/settingslib/development/AbstractEnableAdbPreferenceController.java | ADB_ENABLED |
packages/apps/Settings/src/com/android/settings/development/EnableAdbWarningDialog.java | |
frameworks/base/core/java/android/provider/Settings.java | ADB_ENABLED 常量 |
frameworks/base/services/core/java/com/android/server/adb/AdbService.java | |
frameworks/base/services/core/java/com/android/server/adb/AdbDebuggingManager.java | |
frameworks/base/services/usb/java/com/android/server/usb/UsbDeviceManager.java | IAdbTransport,更新 USB gadget function |
system/core/rootdir/init.usb.rcinit.usb.configfs.rc | sys.usb.config 启停并配置 gadget |
10. 结论
当前实现的核心设计是 设置与执行解耦:
Settings UI 只写 Settings.Global.ADB_ENABLED。AdbService作为中枢监听设置,按 USB / WiFi 传输类型分发,并通过ctl.start/ctl.stop启停 adbd。UsbDeviceManager通过IAdbTransport回调被解耦地通知,负责 USB gadget 配置。AdbDebuggingManager专注 RSA 鉴权与授权。
点击一个开关的背后,仍是 SettingsProvider、system_server(AdbService / UsbDeviceManager)、init、kernel USB gadget 与 adbd 的多层协作。
更多vip干货独享知识,及面试定制指导上岸fw工程师服务,课程优惠购买成为vip学员进入vip群,积极讨论各种行业难点痛点疑难问题,答疑服务等。
请联系马哥微信:

夜雨聆风