跳转至

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

评论