Android 15 CarService源码07-CarWifiService
接口¶
ICarWifi.aidl¶
// packages/services/Car/car-lib/src/android/car/wifi/ICarWifi.aidl
/**
* ICarWifi 是一个内部 Binder 接口,用于定义 CarWifiService 的功能。
* 该接口由 CarWifiManager 使用,用于与 CarWifiService 进行通信。
*
* 作用:
* 1. 提供与 CarWifiService 的通信桥梁。
* 2. 定义 CarWifiService 提供的功能(如检查是否可以控制持久化网络共享设置)。
*
* 注意:
* - 该接口使用 AIDL(Android Interface Definition Language)定义。
* - 由于标记了 `@hide`,该接口仅供系统内部使用,不会暴露给第三方应用。
*/
interface ICarWifi {
/**
* 检查是否可以控制持久化网络共享设置。
*
* 作用:
* - 该方法由 CarWifiManager 调用,用于检查当前系统是否支持控制持久化网络共享设置。
* - 返回值为布尔值,`true` 表示支持,`false` 表示不支持。
*
* 使用场景:
* - CarWifiManager 在尝试更改持久化网络共享设置之前,会调用此方法进行权限检查。
*
* @return {@code true} 如果可以控制持久化网络共享设置;否则返回 {@code false}。
*/
boolean canControlPersistTetheringSettings();
}
ICarWifi
是一个 AIDL 接口,用于定义 CarWifiService
提供的功能。它的主要作用是作为 CarWifiService
和 CarWifiManager
之间的通信桥梁。
通过 ICarWifi
接口,CarWifiManager
可以调用 CarWifiService
提供的功能,例如检查是否可以控制持久化网络共享设置。
canControlPersistTetheringSettings()
检查当前系统是否允许控制持久化网络共享设置。
- true
:表示系统支持持久化网络共享设置,并且当前用户有权限控制它。
- false
:表示系统不支持该功能,或者当前用户无权限。
CarWifiManager¶
// packages/services/Car/car-lib/src/android/car/wifi/CarWifiManager.java
/**
* CarWifiManager 提供 API,允许应用程序执行与 Wi-Fi 相关的操作。
*
* 主要功能:
* 1. 作为客户端接口,与 CarWifiService 通信。
* 2. 提供高层次的 API,供系统内的模块或应用程序使用。
* 3. 封装了与 CarWifiService 的交互细节,简化了客户端的使用。
*/
@SystemApi
@FlaggedApi(Flags.FLAG_PERSIST_AP_SETTINGS)
public final class CarWifiManager extends CarManagerBase {
// ICarWifi 是 CarWifiService 的 AIDL 接口,用于与 CarWifiService 进行通信。
private final ICarWifi mService;
/**
* 构造函数,用于初始化 CarWifiManager。
*
* @param car CarBase 对象,用于管理与车载服务的连接。
* @param service IBinder 对象,表示 CarWifiService 的远程服务接口。
*
* 作用:
* - 将 IBinder 转换为 ICarWifi 接口,供后续调用。
* - 通过父类 CarManagerBase 初始化与车载服务的连接。
*
* @hide
*/
public CarWifiManager(ICarBase car, IBinder service) {
super(car); // 调用父类的构造函数,初始化与车载服务的基本连接。
mService = ICarWifi.Stub.asInterface(service); // 将 IBinder 转换为 ICarWifi 接口。
}
/**
* 当与车载服务的连接断开时调用。
*
* 作用:
* - 这是一个回调方法,用于处理与车载服务断开连接的场景。
* - 当前实现为空,表示不需要特殊处理。
*
* @hide
*/
@Override
public void onCarDisconnected() {}
/**
* 检查是否可以控制持久化网络共享设置。
*
* 作用:
* - 调用 CarWifiService 提供的 `canControlPersistTetheringSettings()` 方法。
* - 返回布尔值,表示当前系统是否支持持久化网络共享设置的控制。
*
* 使用场景:
* - 系统模块或应用程序在尝试更改持久化网络共享设置之前,会调用此方法进行检查。
*
* 权限要求:
* - 调用此方法需要 `Car.PERMISSION_READ_PERSIST_TETHERING_SETTINGS` 权限。
*
* @return {@code true} 如果可以控制持久化网络共享设置;否则返回 {@code false}。
*
* @hide
*/
@SystemApi
@FlaggedApi(Flags.FLAG_PERSIST_AP_SETTINGS)
@RequiresPermission(Car.PERMISSION_READ_PERSIST_TETHERING_SETTINGS)
public boolean canControlPersistTetheringSettings() {
try {
// 调用 CarWifiService 的 AIDL 接口方法。
return mService.canControlPersistTetheringSettings();
} catch (RemoteException e) {
// 如果发生远程通信异常,调用父类方法处理异常并返回默认值(false)。
return handleRemoteExceptionFromCarService(e, false);
}
}
}
CarWifiManager
是一个 客户端管理类,用于与 CarWifiService
交互。
canControlPersistTetheringSettings()
用于检查当前系统是否支持控制持久化网络共享设置。
初始化¶
根据 Android 15 CarService源码02-服务初始化 的分析,CarService 服务的初始化过程实际上包括以下几个步骤:
-
Native服务的初始化:
- 首先,构建每个
HalService
实例。 - 然后,调用
HalService
的takeProperties()
方法。 - 接着,调用
HalService
的init()
方法。
- 首先,构建每个
-
Java服务的初始化:
- 构建每个
CarSystemService
实例。 - 调用
CarSystemService
的init()
方法。 - 最后,调用
CarSystemService
的onInitComplete()
方法。
- 构建每个
CarWifiService
不需要与 VehicleHal
进行交互,因此没有相关的 HalService
。因此,我们可以直接从 CarWifiService
开始进行分析。
CarWifiService¶
CarWifiService构造函数¶
// packages/services/Car/service/src/com/android/car/wifi/CarWifiService.java
/**
* CarWifiService 是一个专门为车载系统设计的服务,负责管理 Wi-Fi 热点功能。
* 它能够根据汽车的电源状态、用户设置以及系统配置来启用或禁用 Wi-Fi 热点。
* 主要功能包括:
* 1. 持久化 Wi-Fi 热点的状态(启用或禁用)。
* 2. 在系统启动或用户解锁后,根据持久化的状态自动恢复 Wi-Fi 热点。
* 3. 监听系统配置的变化,例如是否启用持久化网络共享功能。
* 4. 与汽车电源管理和用户管理服务集成,确保热点功能在合适的时机启动或关闭。
*/
public final class CarWifiService extends ICarWifi.Stub implements CarServiceBase {
// 上下文对象,用于访问系统服务和资源。
private final Context mContext;
// 是否启用持久化网络共享功能(从资源配置中读取)。
private final boolean mIsPersistTetheringCapabilitiesEnabled;
// 是否启用持久化网络共享设置(从系统设置中读取)。
private final boolean mIsPersistTetheringSettingEnabled;
// Wi-Fi 管理器,用于管理 Wi-Fi 热点。
private final WifiManager mWifiManager;
// 网络共享管理器,用于启动或停止网络共享功能。
private final TetheringManager mTetheringManager;
// 汽车电源管理服务,用于监听汽车电源状态。
private final CarPowerManagementService mCarPowerManagementService;
// 汽车用户服务,用于监听系统用户的解锁状态。
private final CarUserService mCarUserService;
public CarWifiService(Context context) {
mContext = context;
// 从资源配置中读取是否启用持久化网络共享功能。
mIsPersistTetheringCapabilitiesEnabled = context.getResources().getBoolean(R.bool.config_enablePersistTetheringCapabilities);
// 从系统设置中读取是否启用持久化网络共享设置。
mIsPersistTetheringSettingEnabled = mFeatureFlags.persistApSettings() &&
TextUtils.equals("true", Settings.Global.getString(context.getContentResolver(), ENABLE_PERSISTENT_TETHERING));
// 初始化 Wi-Fi 和网络共享管理器。
mWifiManager = context.getSystemService(WifiManager.class);
mTetheringManager = context.getSystemService(TetheringManager.class);
// 初始化汽车电源管理服务和用户服务。
mCarPowerManagementService = CarLocalServices.getService(CarPowerManagementService.class);
mCarUserService = CarLocalServices.getService(CarUserService.class);
}
}
CarWifiService
主要用于管理 Wi-Fi 热点功能。构造函数主要是初始化服务所需的系统服务和配置。
CarWifiService.init()¶
// packages/services/Car/service/src/com/android/car/wifi/CarWifiService.java
public final class CarWifiService extends ICarWifi.Stub implements CarServiceBase {
@Override
public void init() {
if (!mIsPersistTetheringCapabilitiesEnabled) {
Slogf.w(TAG, "Persist tethering capability is not enabled");
return;
}
// 注册 Wi-Fi 热点状态回调。
mWifiManager.registerSoftApCallback(mHandler::post, mSoftApCallback);
// 在用户 0 解锁时执行初始化操作。
mCarUserService.runOnUser0Unlock(this::onSystemUserUnlocked);
// 注册汽车电源状态监听器。
mCarPowerManagementService.registerListener(mCarPowerStateListener);
if (mFeatureFlags.persistApSettings()) {
// 注册内容观察者,监听持久化网络共享设置的变化。
mContext.getContentResolver().registerContentObserver(Settings.Global.getUriFor(
ENABLE_PERSISTENT_TETHERING), false, mPersistTetheringObserver);
}
}
}
init()
方法主要是注册 Wi-Fi 热点状态回调、电源状态监听器和内容观察者,以便在系统中进行相应的操作。
SoftApCallback¶
// packages/services/Car/service/src/com/android/car/wifi/CarWifiService.java
public final class CarWifiService extends ICarWifi.Stub implements CarServiceBase {
// Soft AP(Wi-Fi 热点)状态回调,用于监听热点状态的变化。
private final SoftApCallback mSoftApCallback = new SoftApCallback() {
@Override
public void onStateChanged(int state, int failureReason) {
switch (state) {
case WIFI_AP_STATE_ENABLED -> {
// 当 Wi-Fi 热点成功启用时:
Slogf.i(TAG, "AP enabled successfully");
synchronized (mLock) {
if (mSharedPreferences != null) {
// 将热点启用状态保存到 SharedPreferences 中。
Slogf.i(TAG, "WIFI_AP_STATE_ENABLED received, saving state in SharedPreferences store");
mSharedPreferences.edit().putBoolean(KEY_PERSIST_TETHERING_ENABLED_LAST, true).apply();
}
}
// 如果持久化功能和设置均启用,则禁用热点的自动关闭功能。
if (mIsPersistTetheringCapabilitiesEnabled && mIsPersistTetheringSettingEnabled) {
setSoftApAutoShutdownEnabled(false);
}
}
case WIFI_AP_STATE_DISABLED -> {
// 当 Wi-Fi 热点被禁用时:
synchronized (mLock) {
if (mSharedPreferences != null) {
// 将热点禁用状态保存到 SharedPreferences 中。
Slogf.i(TAG, "WIFI_AP_STATE_DISABLED received, saving state in SharedPreferences store");
mSharedPreferences.edit().putBoolean(KEY_PERSIST_TETHERING_ENABLED_LAST, false).apply();
}
}
}
case WIFI_AP_STATE_FAILED -> {
// 当 Wi-Fi 热点启用失败时:
Slogf.w(TAG, "WIFI_AP_STATE_FAILED state received");
// 此时不更改 SharedPreferences 中的状态,保持之前的设置。
}
default -> {
// 其他状态不处理。
}
}
}
};
}
SoftApCallback
是一个接口,用于监听 Wi-Fi 热点(Soft AP)的状态变化。
- WIFI_AP_STATE_ENABLED:将热点启用状态保存到
SharedPreferences
中。 - WIFI_AP_STATE_DISABLED:将热点禁用状态保存到
SharedPreferences
中。 - WIFI_AP_STATE_FAILED:热点启用失败时的处理。不更改
SharedPreferences
中的状态,保持之前的设置。
CarWifiService.onSystemUserUnlocked()¶
// packages/services/Car/service/src/com/android/car/wifi/CarWifiService.java
public final class CarWifiService extends ICarWifi.Stub implements CarServiceBase {
/**
* 当系统用户 0 解锁时调用。
*/
private void onSystemUserUnlocked() {
synchronized (mLock) {
// 初始化 SharedPreferences,用于存储 Wi-Fi 热点状态。
mSharedPreferences = mContext.getSharedPreferences(SHARED_PREF_NAME, Context.MODE_PRIVATE);
}
if (mCarPowerManagementService.getPowerState() == CarPowerManager.STATE_ON) {
startTethering();
}
}
}
系统用户 0 解锁时初始化 Wi-Fi 热点状态的存储,并根据当前的电源状态决定是否启动网络共享。
CarWifiService.startTethering()¶
// packages/services/Car/service/src/com/android/car/wifi/CarWifiService.java
public final class CarWifiService extends ICarWifi.Stub implements CarServiceBase {
/**
* 启动 Wi-Fi 热点(如果之前启用了持久化设置)。
* 该方法会检查系统配置和用户设置,以决定是否启动 Wi-Fi 热点。
*/
private void startTethering() {
// 检查是否启用了持久化网络共享功能和设置。
// 如果系统不支持持久化功能或用户未启用持久化设置,则不启动热点。
if (!mIsPersistTetheringCapabilitiesEnabled || !mIsPersistTetheringSettingEnabled) {
return; // 退出方法,不进行任何操作。
}
// 检查当前 Wi-Fi 热点是否已经启用。
// 如果热点已经启用,则不需要再次启动。
if (mWifiManager.isWifiApEnabled()) {
return; // 退出方法,不进行任何操作。
}
// 使用同步块确保线程安全地访问共享资源 mSharedPreferences。
synchronized (mLock) {
// 检查 SharedPreferences 是否已初始化,以及之前的热点状态是否为启用。
// 如果 SharedPreferences 未初始化或之前的状态为未启用,则不启动热点。
if (mSharedPreferences == null || !mSharedPreferences.getBoolean(
KEY_PERSIST_TETHERING_ENABLED_LAST, false)) {
Slogf.d(TAG, "Tethering was not enabled last");
return; // 退出方法,不进行任何操作。
}
}
// 使用 TetheringManager 启动 Wi-Fi 热点。
// TETHERING_WIFI 指定要启动的网络共享类型为 Wi-Fi。
// mHandler::post 用于在指定的处理器上执行回调。
mTetheringManager.startTethering(TETHERING_WIFI, mHandler::post, new StartTetheringCallback() {
@Override
public void onTetheringFailed(int error) {
// 如果启动失败,记录错误日志。
Slogf.e(TAG, "Starting tethering failed: %d", error);
}
});
}
}
startTethering()
方法通过一系列条件检查,确保只有在适当的情况下才启动 Wi-Fi 热点。
ICarPowerStateListener¶
// packages/services/Car/service/src/com/android/car/wifi/CarWifiService.java
public final class CarWifiService extends ICarWifi.Stub implements CarServiceBase {
// 电源状态监听器,用于监听汽车电源状态的变化。
private final ICarPowerStateListener mCarPowerStateListener = new ICarPowerStateListener.Stub() {
@Override
public void onStateChanged(int state, long expirationTimeMs) {
// 当汽车电源状态变为 "ON" 时,调用 onStateOn 方法。
if (state == CarPowerManager.STATE_ON) {
onStateOn();
}
}
};
/**
* 当汽车电源状态变为 "ON" 时调用。
*/
private void onStateOn() {
synchronized (mLock) {
if (mSharedPreferences == null) {
Slogf.d(TAG, "SharedPreferences store has not been initialized");
return;
}
}
startTethering();
}
}
当汽车电源状态变为 "ON" 时调用 startTethering()
。
mPersistTetheringObserver¶
// packages/services/Car/service/src/com/android/car/wifi/CarWifiService.java
public final class CarWifiService extends ICarWifi.Stub implements CarServiceBase {
// 内容观察者,用于监听持久化网络共享设置的变化。
// 当用户或系统改变了持久化网络共享设置时,该观察者会被触发。
private final ContentObserver mPersistTetheringObserver = new ContentObserver(mHandler) {
@Override
public void onChange(boolean selfChange) {
// 记录日志,指示持久化网络共享设置已发生变化。
Slogf.i(TAG, "%s setting has changed", ENABLE_PERSISTENT_TETHERING);
// 检查当前持久化网络共享设置是否启用。
// mFeatureFlags.persistApSettings() 检查系统是否支持持久化设置。
// Settings.Global.getString() 从全局设置中获取持久化设置的当前值,并与 "true" 比较。
boolean persistTetheringSettingEnabled = mFeatureFlags.persistApSettings() &&
TextUtils.equals("true", Settings.Global.getString(mContext.getContentResolver(), ENABLE_PERSISTENT_TETHERING));
// 根据持久化设置的状态,启用或禁用热点的自动关闭功能。
// 如果持久化设置被关闭,则启用自动关闭功能。
setSoftApAutoShutdownEnabled(!persistTetheringSettingEnabled);
}
};
/**
* 设置 Wi-Fi 热点的自动关闭功能。
* @param enable 如果为 true,则启用自动关闭功能;如果为 false,则禁用自动关闭功能。
*/
private void setSoftApAutoShutdownEnabled(boolean enable) {
// 获取当前的热点配置,并使用 Builder 模式创建新的配置。
SoftApConfiguration config = new SoftApConfiguration.Builder(
mWifiManager.getSoftApConfiguration())
// 设置自动关闭功能的启用状态。
.setAutoShutdownEnabled(enable)
// 构建新的热点配置。
.build();
// 将新的配置应用到 Wi-Fi 热点。
mWifiManager.setSoftApConfiguration(config);
}
}
内容观察者 mPersistTetheringObserver
监听持久化网络共享设置的变化,并根据设置的状态调整 Wi-Fi 热点的自动关闭功能。
CarWifiService.onInitComplete()¶
这里的 CarWifiService 不重 CarSystemService.onInitComplete() 方法而直接使用默认实现。
总结¶
CarWifiService
类的主要功能是管理和控制汽车中的 Wi-Fi 热点(Soft AP)功能。
- 提供启动和停止 Wi-Fi 热点的功能。
- 通过
startTethering()
方法,根据系统配置和用户设置启动 Wi-Fi 热点。 - 监听和响应持久化网络共享设置的变化。
- 使用
ContentObserver
监听系统中持久化网络共享设置的变化,当设置改变时,调整 Wi-Fi 热点的自动关闭功能。 - 根据持久化设置的状态,启用或禁用 Wi-Fi 热点的自动关闭功能。
- 使用
setSoftApAutoShutdownEnabled()
方法设置热点的自动关闭配置。 - 通过
SharedPreferences
保存和恢复 Wi-Fi 热点的状态,确保在系统重启或用户切换后能够恢复之前的热点状态。