乐于分享
好东西不私藏

安卓点下“USB调试”后,系统到底做了什么?AOSP源码剖析

安卓点下“USB调试”后,系统到底做了什么?AOSP源码剖析
背景:

在平常首次使用手机进行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.javaGlobal.ADB_ENABLED = "adb_enabled")。


3. 系统服务层:谁在监听 ADB_ENABLED

AdbService 在构造时注册 AdbSettingsObserver,同时监听两个 URI:

URI
对应传输类型
Settings.Global.ADB_ENABLED
USB 调试
Settings.Global.ADB_WIFI_ENABLED
无线调试(WiFi)

文件: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 行)做三件事:

  1. startAdbd() / stopAdbd()
  2. 通知所有注册的 IAdbTransport(其中就有 UsbDeviceManager
  3. 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 的启停由两条路径共同完成:

  1. ctl.start=adbd / ctl.stop=adbd:由 AdbService 直接写属性触发 init 启停进程。
  2. 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
adbd 未运行或未响应
unauthorized
adbd 运行但未完成 RSA 鉴权
device
鉴权通过,主机可正常调试

当 ro.adb.secure = 1 时,主机公钥由 AdbDebuggingManager 处理:不在 /data/misc/adb/adb_keys 中则弹授权框,用户允许后写入并回传确认,状态变为 device


8. 完整时序总结

开启(首次)

  1. 用户点击 enable_adb 开关。
  2. AbstractEnableAdbPreferenceController.handlePreferenceTreeClick() 弹出 EnableAdbWarningDialog
  3. 用户确认 → onEnableAdbDialogConfirmed() → writeAdbSetting(true) → Settings.Global.ADB_ENABLED = 1
  4. AdbService.AdbSettingsObserver 收到变化 → setAdbEnabled(true, USB)
  5. startAdbd() 写 ctl.start=adbd,adbd 启动。
  6. 回调 IAdbTransport.onAdbEnabled() → UsbDeviceManager.setAdbEnabled(true) 写 persist.sys.usb.config 加入 adb,并触发 sys.usb.config 变化。
  7. init 重配 USB gadget,绑定 adb function,设备重新枚举。
  8. AdbDebuggingManager 处理 RSA 鉴权,主机 adb devices 先 unauthorized,授权后变 device

关闭

  1. handlePreferenceTreeClick() 直接 writeAdbSetting(false) → ADB_ENABLED = 0
  2. AdbService.setAdbEnabled(false, USB) → 若 WiFi 也未开启则 ctl.stop=adbd
  3. 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
ADB 开关 Controller(薄封装)
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
监听设置、启停 adbd、分发到各 transport
frameworks/base/services/core/java/com/android/server/adb/AdbDebuggingManager.java
ADB 鉴权与授权
frameworks/base/services/usb/java/com/android/server/usb/UsbDeviceManager.java
实现 IAdbTransport,更新 USB gadget function
system/core/rootdir/init.usb.rc
 / init.usb.configfs.rc
定义 adbd 服务、按 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 的多层协作。

入门到精通的安卓framework学习课表如下:
Android Framework开发rom实战合集课表/车载车机手机高级系统开发工程必会技能
重大消息:Hal+perfetto-systrace+SurfaceFlinger合集新专题发布
重大消息:ShellTransition项目实战专题aosp15版本首发优惠获取
开学第一课:安卓音频框架Audio子系统实战专题--首发优惠活动
2026第一课:安卓14-1车机手机三分屏实战专题--首发优惠活动

更多vip干货独享知识,及面试定制指导上岸fw工程师服务,课程优惠购买成为vip学员进入vip群,积极讨论各种行业难点痛点疑难问题,答疑服务等。

请联系马哥微信: