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 热点的状态,确保在系统重启或用户切换后能够恢复之前的热点状态。