Android wifi探究四:Wifi P2P framework层源码分析

本文深入探讨了Android Framework中Wi-Fi P2P服务的工作机制,从Messenger到WifiP2pServiceImpl,再到P2pStateMachine,分析了如何通过Channel与服务端交互,包括initialize方法的实现和discoverPeers方法的调用流程。

上一篇博客对应用程序下使用Wi-Fi P2P Api连接附近的设备的过程做了一个简单的梳理,我们只是学会了怎么使用api,但对api背后的机制一无所知。那么这篇博客就开始尝试分析api背后的实现机制,也就是android framework中Wi-Fi P2P的工作机制。
Wifi P2P在framework层也是一个Service,它的启动过程和WifiService一样:

                mSystemServiceManager.startService(WIFI_P2P_SERVICE_CLASS);
                mSystemServiceManager.startService(WIFI_SERVICE_CLASS);

所以就在不啰嗦了,感兴趣可惜浏览下 Android wifi探究二:java层的wifi框架 这篇文章,我们感兴趣的是WifiP2pServiceImpl是怎么工作的,怎么和应用程序交互的。比如当应用程序调用discoverPeers方法发起查找时,WifiP2pServiceImpl做了什么工作。
回顾上一篇博客的内容,我们使用Wifi P2P服务时,首先要获取到WifiP2pManager 的实例:

mManager = (WifiP2pManager) getSystemService(Context.WIFI_P2P_SERVICE);

之后的操作都是调用WifiP2pManager 中的方法实现的。我们知道我们向系统注册的Wi-Fi P2P服务是WifiP2pServiceImpl,他们之间会使用一定的机制进行通信,当然主要就是Binder了,不过,还有一个很重要的知识点,那就是Messenger。

一.Messenger

浏览下WifiP2pServiceImpl的实现,因为之前已经分析过WifiServiceImpl的实现,对比我们就知道WifiP2pServiceImpl内部也有个状态机,状态机是消息驱动的,我们需要给状态机发消息才能促使状态机切换状态,那么我们能不能在WifiP2pManager 中直接给WifiP2pServiceImpl发消息呢?答案是能。怎么发呢?就是这里要介绍的Messenger。
我们看一下Api文档中对它的介绍:
Reference to a Handler, which others can use to send messages to it. This allows for the implementation of message-based communication across processes, by creating a Messenger pointing to a Handler in one process, and handing that Messenger to another process.

Note: the implementation underneath is just a simple wrapper around a Binder that is used to perform the communication. This means semantically you should treat it as such: this class does not impact process lifecycle management (you must be using some higher-level component to tell the system that your process needs to continue running), the connection will break if your process goes away for any reason,

翻译(英语太菜,翻译有误请包涵):
我们可以使用Handler引用来发消息,我们可以创建一个Messenger实例,这个实例指向一个进程中的Handler,这样我们可以在另一个进程中处理Messenger 发过来的消息。这样就实现了基于消息的进程间的通信。
注意:实现的原理就是对Binder做一个封装。这意味着:这个类不影响进程的生命周期(你必须使用高级别的组件告诉系统的进程需要继续运行),如果另一进程消失了的话,连接就会断开。
那么,Messanger是怎么获取的呢?
WifiP2pManager 中:

    public Messenger getMessenger() {
        try {
            return mService.getMessenger();
        } catch (RemoteException e) {
            return null;
        }
    }

mService就是WifiP2pServiceImpl的客户端,我们看下WifiP2pServiceImpl中的getMessenger方法:

    public Messenger getMessenger() {
        enforceAccessPermission();
        enforceChangePermission();
        return new Messenger(mClientHandler);
    }

mClientHandler就是WifiP2pServiceImpl用来发送和处理消息的Handler实例,因此我们可以知道,WifiP2pManager 中的Messenger 是Binder的一个客户端,调用WifiP2pManager 中Messeng

<think>我们正在分析WifiP2P在Framework源码。根据提供的参考资料,我们可以从状态机(mP2pStateMachine)入手,特别是在P2pEnabledState状态下处理DISCOVER_PEERS消息的流程。此外,我们还要结合WifiNative和WifiP2pManager的相关方法。首先,我们注意到引用[1]中提到,当打开Wi-Fi后,系统也会使能Wi-FiP2P,此时mP2pStateMachine处于P2pEnabledState状态。当收到DISCOVER_PEERS消息时,会执行一段代码。这段代码首先检查mDiscoveryBlocked,如果为真则返回BUSY状态。否则,它会清除服务请求,然后调用mWifiNative.p2pFind方法,根据返回结果回复成功或失败。引用[2]提到了JNI的调用,例如android_net_wifi_startSupplicant函数,它会调用wifi_start_supplicant方法,并且参数p2pSupported表示是否支持P2P。引用[3]则提到WifiService的启动以及wpa_supplicant的作用,但这里我们更关注P2P部分。为了详细分析WifiP2Pframework源码,我们按照以下步骤进行:1.**WifiP2P的初始化**:在系统启动时,WifiService会被启动(如引用[3]),同时初始化P2P相关的状态机。2.**状态机分析**:重点分析P2pEnabledState状态,它是P2P功能使能后的状态,处理各种P2P操作,如发现对等设备(DISCOVER_PEERS)。3.**消息处理流程**:以DISCOVER_PEERS消息为例,分析从应用调用发现对等设备到framework处理,再到JNI调用的过程。4.**与wpa_supplicant的交互**:通过WifiNative类调用wpa_supplicant提供的P2P命令(如p2p_find)。接下来,我们详细分析上述步骤,并参考给出的代码片段。###1.WifiP2P的初始化在Android系统中,WifiService是系统服务之一,启动时会创建WifiStateMachine(在较早版本)或WifiServiceImpl(在较新版本)等。同时,也会初始化P2P相关的模块,例如创建P2pStateMachine。在引用[3]中提到的WifiService启动过程中,会初始化WifiP2pService,它负责管理P2P功能。在WifiP2pService的启动过程中,会创建P2pStateMachine并启动它。###2.状态机分析P2pStateMachine是处理P2P操作的核心状态机。在系统使能Wi-FiP2P后,状态机进入P2pEnabledState。在这个状态下,它可以处理各种P2P消息,如DISCOVER_PEERS(发现对等设备)、CONNECT(连接对等设备)等。引用[1]中展示了在P2pEnabledState状态下处理DISCOVER_PEERS消息的代码片段。该代码段的主要逻辑是:-检查当前是否阻止了发现操作(mDiscoveryBlocked),如果阻止了,则回复失败(BUSY)。-清除之前的服务请求(clearSupplicantServiceRequest)。-调用mWifiNative.p2pFind方法,该方法会向wpa_supplicant发送P2P_FIND命令(实际命令可能是"P2P_FIND")来开始搜索设备。-根据mWifiNative.p2pFind的返回值,回复成功或失败消息,并广播发现状态的变化。###3.消息处理流程当应用调用WifiP2pManager.discoverPeers()时,会通过Binder调用到WifiP2pService,然后向P2pStateMachine发送DISCOVER_PEERS消息。状态机在当前状态(P2pEnabledState)处理该消息。###4.与wpa_supplicant的交互WifiNative类封装了与wpa_supplicant通信的JNI方法。例如,p2pFind方法最终会调用到wpa_supplicant的"P2P_FIND"命令。引用[2]展示了JNI的一个例子,即如何启动wpa_supplicant(通过wifi_start_supplicant方法)。而对于P2P命令,在JNI会有对应的方法(如android_net_wifi_P2pFind)来调用底函数。下面,我们以发现对等设备(DISCOVER_PEERS)为例,详细描述整个流程:1.**应用**:调用`WifiP2pManager.discoverPeers(Channel,WifiP2pManager.ActionListener)`2.**Framework**:通过Binder调用到`WifiP2pService`,然后向`P2pStateMachine`发送`DISCOVER_PEERS`消息。3.**状态机处理**:在`P2pEnabledState`中处理该消息,代码如引用[1]所示。其中,关键调用是`mWifiNative.p2pFind(DISCOVER_TIMEOUT_S)`。4.**WifiNative.p2pFind**:这是一个本地方法,它通过JNI调用到底C++代码。5.**JNI**:例如,在`android_net_wifi_WifiNative.cpp`中,有`P2pFind`方法,它最终会调用`wpa_supplicant`的`ctrl_request`函数发送"P2P_FIND"命令(可能需要带上超时参数)。整个调用链为:应用->WifiP2pManager->WifiP2pService->P2pStateMachine->WifiNative->wpa_supplicant总结:WifiP2Pframework源码主要集中在`WifiP2pService`和`P2pStateMachine`中,通过状态机管理P2P的各种状态和操作,并通过`WifiNative`与底的wpa_supplicant进行交互。§§相关问题§§1.P2pStateMachine有哪些主要状态?它们之间如何转换?2.WifiNative类在P2P功能中扮演什么角色?3.WifiP2P在framework是如何处理多个并发请求的?</think> ### Wifi P2P Framework 源码详细分析 Wifi P2P(Peer-to-Peer)框架位于 Android 系统服务,是连接应用与底驱动的核心组件。其核心实现集中在 `WifiP2pService` 和状态机设计中,以下是关键模块分析: --- #### 1. **核心服务初始化** - **入口点**:`WifiP2pService` 在 SystemServer 启动时初始化 - **依赖项**: - 通过 `WifiNative` 调用 HAL 接口(见引用[2]) ```java // frameworks/opt/net/wifi/service/java/com/android/server/wifi/p2p/WifiP2pService.java public void onBootPhase(int phase) { if (phase == PHASE_SYSTEM_SERVICES_READY) { mP2pStateMachine = new P2pStateMachine("WifiP2pService", ...); mP2pStateMachine.start(); // 启动状态机 } } ``` - **JNI 桥接**:通过 `wifi_start_supplicant(p2pSupported)` 启用 P2P 功能(见引用[2]) --- #### 2. **状态机核心设计** 核心状态机 `P2pStateMachine` 包含以下关键状态: | **状态** | **作用** | |----------------------|-----------------------------------------| | `P2pDisabledState` | P2P 功能未激活时的默认状态 | | `P2pEnabledState` | P2P 激活后主状态(处理主要操作) | | `GroupCreatingState` | 设备组建立过程中的临时状态 | > **状态转换触发条件**: > - 系统使能 Wi-Fi 时自动进入 `P2pEnabledState` > - 收到 `WifiP2pManager.DISABLE_P2P` 消息返回 `P2pDisabledState` --- #### 3. **DISCOVER_PEERS 流程分析** 当应用调用 `discoverPeers()` 时: ```java // frameworks/opt/net/wifi/service/java/com/android/server/wifi/p2p/WifiP2pServiceImpl.java public void discoverPeers(Channel c) { sendMessage(DISCOVER_PEERS); // 发送消息到状态机 } ``` 在 `P2pEnabledState` 的处理逻辑(引用[1]关键代码): ```java case WifiP2pManager.DISCOVER_PEERS: if (mDiscoveryBlocked) { replyToMessage(message, WifiP2pManager.DISCOVER_PEERS_FAILED, WifiP2pManager.BUSY); break; } clearSupplicantServiceRequest(); // 清除旧请求 if (mWifiNative.p2pFind(DISCOVER_TIMEOUT_S)) { // 调用底发现 replyToMessage(message, WifiP2pManager.DISCOVER_PEERS_SUCCEEDED); sendP2pDiscoveryChangedBroadcast(true); // 发送广播通知系统 } else { replyToMessage(message, WifiP2pManager.DISCOVER_PEERS_FAILED, WifiP2pManager.ERROR); } break; ``` --- #### 4. **底交互机制** - **WifiNative 调用链**: ```java // frameworks/opt/net/wifi/service/java/com/android/server/wifi/WifiNative.java public boolean p2pFind(int timeout) { return doBooleanCommand("P2P_FIND " + timeout); // 发送指令到 wpa_supplicant } ``` - **JNI 实现**:通过 `android_net_wifi_WifiNative.cpp` 调用 `wpa_ctrl_request()` 与 supplicant 通信[^3] --- #### 5. **事件通知机制** 发现设备后底上报事件路径: 1. wpa_supplicant 通过 socket 上报 `P2P-DEVICE-FOUND` 事件 2. `WifiMonitor` 线程捕获事件并解析 3. 状态机处理 `P2P_DEVICE_FOUND` 事件,更新设备列表 4. 通过 `WifiP2pManager.ACTION_WIFI_P2P_PEERS_CHANGED` 广播通知应用 --- ### 关键设计特点 1. **异步消息驱动**:所有操作通过状态机消息队列处理 2. **阻塞保护**:`mDiscoveryBlocked` 防止重复请求(如已有组建立时) 3. **超时控制**:`DISCOVER_TIMEOUT_S` 默认值为 120 秒 4. **广播通知**:所有状态变更通过 Android 广播机制通知系统 > 源码位置:`frameworks/opt/net/wifi/service/java/com/android/server/wifi/p2p/`[^1][^3]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值