Wi-Fi 模块可更新,这意味着它可在 Android 常规发布周期外的时间接收功能更新。此模块包含以下组件。
图 1. Wi-Fi 模块组件和架构
Wi-Fi 模块具有以下优势。
最终用户可在不同 Android 设备上获得一致的 Wi-Fi 体验,并可通过模块更新解决互操作性问题。
应用开发者面临的平台碎片也更少。
原始设备制造商 (OEM) 可以满足运营商要求,同时也可以减少进行单独自定义的成本(因为他们不需要以不同的方式实现相同的要求)。
Android 12 和 Android 13 的模块边界
packages/modules/Wifi
framework
java/
android/net/wifi
(frameworks/base/wifi/java
中的文件)
tests/
android/net/wifi
(frameworks/base/wifi/tests
中的文件)
aidl-export/
api/
Android.bp
service/
java/
com/android/server/wifi
(frameworks/opt/net/wifi/service/java
中的文件)
tests/
com/android/server/wifi
(frameworks/opt/net/wifi/tests
中的文件)
proto/
Android.bp
proguard.flags
wifi.rc
OsuLogin/
(frameworks/base/packages/OsuLogin
中的文件)ServiceResources/
(Android 12 中的新增项,叠加层 APK 清单存储在此处)res/
(Android 11 中的新增项,从frameworks/base/core/res/res
中提取的 Wi-Fi 配置)AndroidManifest.xml
Android.bp
WifiDialog/
(Android 13 应用中的新增项,用于启动由服务请求的用户对话框的应用存储在此处。)src/
com/android/wifi/dialog
(包含启动对话框的 activity)
AndroidManifest.xml
Android.bp
上方目录还包含仍在模块化系统组件之外的代码,这些代码仍位于其当前位置,例如:
wificond interface
(android.net.wifi.nl80211
软件包中的类,例如WifiNl80211Manager
)- 资源叠加层应用示例
WifiTrackerLib
libwifi_hal
libwifi_system
libwifi_system_iface
OEM 可以借助示例命令将其补丁程序从原项目目录移至新的项目目录。
转移 frameworks/base/wifi 中的补丁程序
在 root/frameworks/base/wifi 中生成补丁文件
git format-patch -1 commit --stdout > patch-file.txt
在 root/packages/modules/Wifi 中应用补丁文件
git am -p2 --directory=framework/ patch-file.txt
转移 frameworks/opt/net/wifi 中的补丁程序
如需转移 frameworks/opt/net/wifi
中的补丁,需要执行复杂的步骤,因为迁移过程中目录层次结构发生了变化。
在 frameworks/opt/net/wifi
中,将提交内容拆分为 2 个提交内容,一个用于 service/
,另一个用于 tests/
。
迁移 HEAD 提交内容
git reset HEAD^
git add service/
git commit # Enter your commit message. Call this commit service-commit
git add tests/
git commit # Enter your commit message. Call this commit test-commit
生成两个提交内容补丁文件
git format-patch -1 service-commit --stdout > service-patch.txt
git format-patch -1 test-commit --stdout > test-patch.txt
在 packages/modules/Wifi 中应用这两个补丁程序
git am service-patch.txt
git am -p1 --directory=service/ test-patch.txt
将这两个提交内容合并成一个
git rebase -i
将第二个提交内容的操作更改为 squash
。
对提交消息进行相应修改。
Android 11 的模块边界
Wi-Fi 服务会继续在系统服务进程内运行。Wi-Fi 模块包含 packages/modules/Wifi
中的所有代码,其中包括:
WifiService
、WifiP2pService
、WifiAwareService
、WifiScannerService
和WifiRttService
的 SDK 和服务类OsuLogin
ServiceWifiResources
该模块不包含以下组件,这些组件仍是 OEM 的 AOSP build 的一部分。
system/connectivity/wificond
中的wificond
原生组件wificond
接口(软件包android.net.wifi.nl80211
中的类,例如WifiNl80211Manager
)android.net.wifi.SoftApConfToXmlMigrationUtil
android.net.wifi.WifiNetworkScoreCache
android.net.wifi.WifiMigration
WifiTrackerLib
libwifi_hal
libwifi_system
libwifi_system_iface
Android 11 不会移动文件,但未来的版本可能会。为了减少移植文件位置变更所涉及的工作量,我们建议将尽可能多的变更向上游传送到 AOSP(在将它们移植到 Android 11 后),或重构专有扩展,以使用正式的 Android API 或供应商 HAL 扩展从 AOSP 代码中剥离它们。
模块格式
Wi-Fi 模块 (com.android.wifi
) 采用 APEX 格式,适用于搭载 Android 11 或更高版本的设备。APEX 文件包含以下组件。
- SDK 库 (
framework-wifi.jar
) - 服务库 (
service-wifi.jar
) - OsuLogin APK (
OsuLoginGoogle.apk
) - 资源 APK (
ServiceWifiResourcesGoogle.apk
) - WFA 证书
模块依赖项
Wi-Fi 模块依赖于以下几项:
- 网络连接
- 电话
- Proto 库
- 其他系统组件
- Wi-Fi HAL
wificond
bouncycastle
ksoap2
libnanohttpd
此模块仅使用稳定的 @SystemApi
(不使用 @hide
API)与框架进行交互,并且使用 Google 签名(而不是平台签名)进行签名。
自定义
Wi-Fi 模块不支持直接自定义,但您可以使用运行时资源叠加层 (RRO) 或运营商配置来自定义配置。
图 2. Wi-Fi 模块自定义
- 对于小规模自定义,请启用或停用 RRO
config
中的设置。 - 为加强控制,请为任何作为
@SystemAPI
提供的运营商配置密钥自定义配置值。
使用运行时资源叠加层
您可以通过使用 RRO 替换默认配置来自定义 Wi-Fi 模块。如需查看可叠加配置的列表,请参阅 packages/modules/Wifi/service/ServiceWifiResources/res/values/overlayable.xml
。如需详细了解配置行为,请参阅 packages/modules/Wifi/service/ServiceWifiResources/res/values/config.xml
。如需查看叠加层应用示例,请参阅 device/google/coral/rro_overlays/WifiOverlay/
。
由于 device/google/coral/rro_overlays/WifiOverlay/AndroidManifest.xml
文件将 targetPackage
属性设置为 com.android.wifi.resources
,并且 Wi-Fi 模块传递的资源 APK 的软件包名称为 com.google.android.wifi.resources
,因此您必须将叠加层 APK 的 targetPackage
设置为 com.google.android.wifi.resources
,才能成功叠加 Wi-Fi 配置。
迁移配置存储格式
Wi-Fi 模块只能解析 AOSP Wi-Fi 配置存储格式。如果您之前修改过 Wi-Fi 配置存储格式(其中包括用户已保存的网络列表),则在将设备升级到任何包含 Wi-Fi 模块的 Android 版本时,您必须将相应数据转换为 AOSP 格式。此转换所需的钩子位于 android.net.wifi.WifiMigration
类中。
通过以下方法实现格式转换。
WifiMigration.convertAndRetrieveSharedConfigStoreFile(<storeFileId>)
由 Wi-Fi 模块调用,以检索已转换为 AOSP 格式的 Wi-Fi 共享存储文件内容。
这些文件之前(在 Android 10 中)存储在设备的
/data/misc/wifi
文件夹中。
WifiMigration.convertAndRetrieveUserConfigStoreFile(<storeFileId>)
由 Wi-Fi 模块调用,以检索已转换为 AOSP 格式的 Wi-Fi 用户专用存储文件内容。
这些文件之前(在 Android 10 中)存储在设备的
/data/misc_ce/<userId>/wifi
文件夹中。
访问隐藏的 Wi-Fi API
Wi-Fi 模块中带有 @hide
注解的符号(类、方法和字段等)不属于其公共 API 接口,不能在已安装该模块的设备上访问。不包含 Wi-Fi 模块的设备可以按照以下步骤继续使用 @hide
Wi-Fi API。
通过将
impl_library_visibility
属性更改为 public,移除了对packages/modules/Wifi/framework/Android.bp
中的framework-wifi
的公开范围限制。java_sdk_library { name: "framework-wifi", ... impl_library_visibility: [ "//visibility:public", // Add this rule and remove others. ], ... }
更改了构建规则,以允许库访问
@hide
Wi-Fi API。例如,以下是java_library
的构建规则。java_library { name: "foo-lib", // no sdk_version attribute defined libs: [ "dependency1", "dependency2", ], }
如需允许对
foo-lib
的库访问权限,请按如下方式更改构建规则。java_library { name: "foo-lib", sdk_version: "core_platform", libs: [ "framework-wifi.impl", "framework", "dependency1", "dependency2", ], }
确保
framework-wifi.impl
在libs
列表中显示在framework
之前。libs
属性中依赖项的顺序很重要。
访问隐藏的框架 API
Wi-Fi 模块外带有 @hide
注解的符号无法通过 Wi-Fi 模块中的代码访问。不包含 Wi-Fi 模块的设备可以继续使用 service-wifi
中的 @hide
外部 API(例如,来自 framework.jar
的 API),但要对 frameworks/opt/net/wifi/service/Android.bp
进行以下修改。
在
wifi-service-pre-jarjar
和service-wifi
中,将sdk_version
属性都更改为core_platform
。在
wifi-service-pre-jarjar
和service-wifi
中,将framework
和android_system_server_stubs_current
添加到libs
属性中。验证结果是否与以下代码示例类似。
java_library { name: "wifi-service-pre-jarjar", ... sdk_version: "core_platform", ... libs: [ ... "framework", "android_system_server_stubs_current", ], } ... java_library { name: "service-wifi", ... sdk_version: "core_platform", ... libs: [ ... "framework", "android_system_server_stubs_current", ], }
Wi-Fi 模块可更新,这意味着它可在 Android 常规发布周期外的时间接收功能更新。此模块包含以下组件。
图 1. Wi-Fi 模块组件和架构
Wi-Fi 模块具有以下优势。
最终用户可在不同 Android 设备上获得一致的 Wi-Fi 体验,并可通过模块更新解决互操作性问题。
应用开发者面临的平台碎片也更少。
OEM 可以满足运营商要求,同时也可以减少进行单独自定义的费用(因为他们不需要以不同的方式实现相同的要求)。
Android 12 的模块边界
packages/modules/Wifi
framework
java/
android/net/wifi
(frameworks/base/wifi/java
中的文件)
tests/
android/net/wifi
(frameworks/base/wifi/tests
中的文件)
aidl-export/
api/
Android.bp
service/
java/
com/android/server/wifi
(frameworks/opt/net/wifi/service/java
中的文件)
tests/
com/android/server/wifi
(frameworks/opt/net/wifi/tests
中的文件)
proto/
Android.bp
proguard.flags
wifi.rc
OsuLogin/
(frameworks/base/packages/OsuLogin
中的文件)ServiceResources/
(Android 12 中的新增项,叠加层 APK 清单存储在此处)res/
(Android 11 中的新增项,从frameworks/base/core/res/res
中提取的 Wi-Fi 配置)AndroidManifest.xml
Android.bp
上方目录还包含仍在模块化系统组件之外的代码,这些代码仍位于其当前位置,例如:
wificond interface
(android.net.wifi.nl80211
软件包中的类,例如WifiNl80211Manager
)- 资源叠加层应用示例
WifiTrackerLib
libwifi_hal
libwifi_system
libwifi_system_iface
OEM 可以借助示例命令将其补丁程序从原项目目录移至新的项目目录。
转移 frameworks/base/wifi 中的补丁程序
在 root/frameworks/base/wifi 中生成补丁文件
git format-patch -1 commit --stdout > patch-file.txt
在 root/packages/modules/Wifi 中应用补丁文件
git am -p2 --directory=framework/ patch-file.txt
转移 frameworks/opt/net/wifi 中的补丁程序
如需转移 frameworks/opt/net/wifi
中的补丁,需要执行复杂的步骤,因为迁移过程中目录层次结构发生了变化。
在 frameworks/opt/net/wifi
中,将提交内容拆分为 2 个提交内容,一个用于 service/
,另一个用于 tests/
。
迁移 HEAD 提交内容
git reset HEAD^
git add service/
git commit # Enter your commit message. Call this commit service-commit
git add tests/
git commit # Enter your commit message. Call this commit test-commit
生成两个提交内容补丁文件
git format-patch -1 service-commit --stdout > service-patch.txt
git format-patch -1 test-commit --stdout > test-patch.txt
在 packages/modules/Wifi 中应用这两个补丁程序
git am service-patch.txt
git am -p1 --directory=service/ test-patch.txt
将这两个提交内容合并成一个
git rebase -i
将第二个提交内容的操作更改为 squash
。
对提交消息进行相应修改。
Android 11 的模块边界
Wi-Fi 服务会继续在系统服务进程内运行。Wi-Fi 模块包含 packages/modules/Wifi
中的所有代码,其中包括:
WifiService
、WifiP2pService
、WifiAwareService
、WifiScannerService
和WifiRttService
的 SDK 和服务类OsuLogin
ServiceWifiResources
该模块不包含以下组件,这些组件仍是 OEM 的 AOSP build 的一部分。
system/connectivity/wificond
中的wificond
原生组件wificond
接口(软件包android.net.wifi.nl80211
中的类,例如WifiNl80211Manager
)android.net.wifi.SoftApConfToXmlMigrationUtil
android.net.wifi.WifiNetworkScoreCache
android.net.wifi.WifiMigration
WifiTrackerLib
libwifi_hal
libwifi_system
libwifi_system_iface
Android 11 不会移动文件,但未来的版本可能会。为了减少移植文件位置变更所涉及的工作量,我们建议将尽可能多的变更向上游传送到 AOSP(在将它们移植到 Android 11 后),或重构专有扩展,以使用正式的 Android API 或供应商 HAL 扩展从 AOSP 代码中剥离它们。
模块格式
Wi-Fi 模块 (com.google.android.wifi.apex
) 采用 APEX 格式,适用于搭载 Android 11 或更高版本的设备。APEX 文件包含以下组件。
- SDK 库 (
framework-wifi.jar
) - 服务库 (
service-wifi.jar
) - OsuLogin APK (
OsuLoginGoogle.apk
) - 资源 APK (
ServiceWifiResourcesGoogle.apk
) - WFA 证书
模块依赖项
Wi-Fi 模块依赖于以下几项:
- 网络连接
- 电话
- Proto 库
- 其他系统组件
- Wi-Fi HAL
wificond
bouncycastle
ksoap2
libnanohttpd
此模块仅使用稳定的 @SystemApi
(不使用 @hide
API)与框架进行交互,并且使用 Google 签名(而不是平台签名)进行签名。
自定义
Wi-Fi 模块不支持直接自定义,但您可以使用运行时资源叠加层 (RRO) 或运营商配置来自定义配置。
图 2. Wi-Fi 模块自定义
- 对于小规模自定义,请启用或停用 RRO
config
中的设置。 - 为加强控制,请为任何作为
@SystemAPI
提供的运营商配置密钥自定义配置值。
使用运行时资源叠加层
您可以通过使用 RRO 替换默认配置来自定义 Wi-Fi 模块。如需查看可叠加配置的列表,请参阅 packages/modules/Wifi/service/ServiceWifiResources/res/values/overlayable.xml
。如需详细了解配置行为,请参阅 packages/modules/Wifi/service/ServiceWifiResources/res/values/config.xml
。如需查看叠加层应用示例,请参阅 device/google/coral/rro_overlays/WifiOverlay/
。
由于 device/google/coral/rro_overlays/WifiOverlay/AndroidManifest.xml
文件将 targetPackage
属性设置为 com.android.wifi.resources
,并且 Wi-Fi 模块传递的资源 APK 的软件包名称为 com.google.android.wifi.resources
,因此您必须将叠加层 APK 的 targetPackage
设置为 com.google.android.wifi.resources
,才能成功叠加 Wi-Fi 配置。
迁移配置存储格式
Wi-Fi 模块只能解析 AOSP Wi-Fi 配置存储格式。如果您之前修改过 Wi-Fi 配置存储格式(其中包括用户已保存的网络列表),则在将设备升级到任何包含 Wi-Fi 模块的 Android 版本时,您必须将相应数据转换为 AOSP 格式。此转换所需的钩子位于 android.net.wifi.WifiMigration
类中。
通过以下方法实现格式转换。
WifiMigration.convertAndRetrieveSharedConfigStoreFile(<storeFileId>)
由 Wi-Fi 模块调用,以检索已转换为 AOSP 格式的 Wi-Fi 共享存储文件内容。
这些文件之前(在 Android 10 中)存储在设备的
/data/misc/wifi
文件夹中。
WifiMigration.convertAndRetrieveUserConfigStoreFile(<storeFileId>)
由 Wi-Fi 模块调用,以检索已转换为 AOSP 格式的 Wi-Fi 用户专用存储文件内容。
这些文件之前(在 Android 10 中)存储在设备的
/data/misc_ce/<userId>/wifi
文件夹中。
访问隐藏的 Wi-Fi API
Wi-Fi 模块中带有 @hide
注解的符号(类、方法和字段等)不属于其公共 API 接口,不能在已安装该模块的设备上访问。不包含 Wi-Fi 模块的设备可以按照以下步骤继续使用 @hide
Wi-Fi API。
通过将
impl_library_visibility
属性更改为 public,移除了对packages/modules/Wifi/framework/Android.bp
中的framework-wifi
的公开范围限制。java_sdk_library { name: "framework-wifi", ... impl_library_visibility: [ "//visibility:public", // Add this rule and remove others. ], ... }
更改了构建规则,以允许库访问
@hide
Wi-Fi API。例如,以下是java_library
的构建规则。java_library { name: "foo-lib", // no sdk_version attribute defined libs: [ "dependency1", "dependency2", ], }
如需允许对
foo-lib
的库访问权限,请按如下方式更改构建规则。java_library { name: "foo-lib", sdk_version: "core_platform", libs: [ "framework-wifi.impl", "framework", "dependency1", "dependency2", ], }
确保
framework-wifi.impl
在libs
列表中显示在framework
之前。libs
属性中依赖项的顺序很重要。
访问隐藏的框架 API
Wi-Fi 模块外带有 @hide
注解的符号无法通过 Wi-Fi 模块中的代码访问。不包含 Wi-Fi 模块的设备可以继续使用 service-wifi
中的 @hide
外部 API(例如,来自 framework.jar
的 API),但要对 frameworks/opt/net/wifi/service/Android.bp
进行以下修改。
在
wifi-service-pre-jarjar
和service-wifi
中,将sdk_version
属性都更改为core_platform
。在
wifi-service-pre-jarjar
和service-wifi
中,将framework
和android_system_server_stubs_current
添加到libs
属性中。验证结果是否与以下代码示例类似。
java_library { name: "wifi-service-pre-jarjar", ... sdk_version: "core_platform", ... libs: [ ... "framework", "android_system_server_stubs_current", ], } ... java_library { name: "service-wifi", ... sdk_version: "core_platform", ... libs: [ ... "framework", "android_system_server_stubs_current", ], }
测试
Android 兼容性测试套件 (CTS) 通过对每个模块版本运行一套全面的 CTS 测试来验证 Wi-Fi 模块的功能。您也可以运行测试、调试和调整 Wi-Fi 中所述的测试。