标签:获取 ade noi service cte c++ 类 包括 add connected
WifiService 在SystemService 进程中被创建,Wifi 相关对象定义:
/frameworks/base/services/java/com/android/server/SystemServer.java
private static final String WIFI_SERVICE_CLASS = "com.android.server.wifi.WifiService"; private static final String WIFI_NAN_SERVICE_CLASS = "com.android.server.wifi.nan.WifiNanService"; private static final String WIFI_P2P_SERVICE_CLASS = "com.android.server.wifi.p2p.WifiP2pService";
SystemService 类进程启动方法run() 调用startOtherService() 方法创建WifiService 进程:
if (context.getPackageManager().hasSystemFeature(PackageManager.FEATURE_WIFI_NAN)) { mSystemServiceManager.startService(WIFI_NAN_SERVICE_CLASS);//mSystemServiceManager 进程管理对象在run()方法中创建 } else { Slog.i(TAG, "No Wi-Fi NAN Service (NAN support Not Present)"); } mSystemServiceManager.startService(WIFI_P2P_SERVICE_CLASS); mSystemServiceManager.startService(WIFI_SERVICE_CLASS); mSystemServiceManager.startService( "com.android.server.wifi.scanner.WifiScanningService"); if (!disableRtt) { mSystemServiceManager.startService("com.android.server.wifi.RttService"); }
对SystemService的研究可参考《深入理解Android:卷II》第3章
WifiService 继承SystemService,包名com.android.service.wifi,其构造函数初始化一个WifiServiceImpl 对象:
public final class WifiService extends SystemService { private static final String TAG = "WifiService"; final WifiServiceImpl mImpl; public WifiService(Context context) { super(context); mImpl = new WifiServiceImpl(context); } }
在此,先介绍两个知识点,分别是HSM(Hierarchical State Machine,结构化状态机)和AsyncChannel。
HSM 和AsyncChannel 介绍
HSM(对应的类是StateMachine) 和AsyncChannel 是Android Framework 中两个重要的类。
HSM 中的状态层级关系与Java中父子类的派生和继承关系类似,即在父状态中实现generic 的功能,而在子状态中实现一些特定的处理;不过与Java 中类派生不同的是,HSM 中父子状态对应的是毫无派生关系的两个类,使用时需要创建两个对象。
AsyncChannel 用于两个Handler 之间的通信,具体的通信方式为源Handler 通过sendMessage 向目标Handler 发送消息,而目标Handler 通过replyToMessage 回复源Handler 处理结果;这两个Handler 可位于同一个进程,也可分属于两个不同的进程。
1、HSM 的使用
addState():添加一个状态。同时还可指定父状态
transitionTo():将状态机切换到某个状态
obtainMessage():HSM内部是围绕一个Handler来工作的,外界只能调用HSM的obtainMessage()以获取一个Message
sendMessage():发送消息给HSM。HSM 中的Handler 会处理它
deferMessage():保留某个消息,该消息将留待下一个新状态中去处理
start():启动状态机
quit()、quitNow():停止状态机
HSM 中状态和状态直接的层级关系体现在:
1) SM启动后,初始状态的EA将按派生顺序执行,即其祖先状态先执行,子状态后执行
2) 当State发送切换时,旧State的exit 先执行,新State 的enter 后执行,并且新旧State 派生树上对应的State 也需要执行exit 或 enter 函数。类似C++ 类构造/析构函数执行顺序
3) State 处理Message 时,如子状态不能处理(返回NOT_HANDLED),则交给父状态去处理
2、AsyncChannel 的使用
1) 简单的request/response 模式下,Server 端无须维护Client 的信息,它只要处理来自Client 的请求即可。
Client 调用connectSync(同步连接)或connect(异步连接,连接成功后Client 会收到CMD_CHANNEL_HALF_CONNECTED 消息)即可连接到Server。
2) 与request/response 模式相反,即Server 端维护Client 的信息。
Server 可以向Client 发送自己的状态或者其他一些有意义的信息。wpa_cli 和wpa_supplicant 就是此模式的应用,wpa_cli 可以发送命令给WPAS 去执行;同时,WPAS 也会将自己的状态及其他一些信息通知给 wpa_cli。
以异步方式为例介绍第2种应用模式中AsyncChannel 的使用步骤:
1) Client 调用AsyncChannel 的connect() 函数,Client 的Handler 会收到一个名为CMD_CHANNEL_HALF_CONNECTED 消息;
2) Client 在处理CMD_CHANNEL_HALF_CONNECTED 消息时,需通过sendMessage() 函数向Server 端发送一个名为 CMD_CHANNEL_FULL_CONNECTION 的消息;
3) Server 端的Handler 将收到此CMD_CHANNEL_FULL_CONNECTION 消息,成功处理它后,Server 端先调用AsyncChannel 的connected() 函数,然后通过sendMessage() 函数向Client 端发送CMD_CHANNEL_FULLY_CONNECTED 消息;
4) Client 端收到CMD_CHANNEL_FULLY_CONNECTED 消息。至此,Client 和Server 端成功建立连接。
5) Clinet 和Server 端的两个Handler 可借助sendMessage() 和replyToMessage() 来完成请求消息及回复消息的传递。注意,只有针对那些需要回复的情况,Server 端才需调用replyToMessage()。
6) Client 和Server 的任意一端都可以调用disconnect() 函数以结束连接。该函数将导致Client 和Server 端都会收到CMD_CHANNEL_DISCONNECTED 消息。
注此部分流程描述来自AsyncChannel.java 文件中的注释,但实际第3步,AsyncChannel 一般由客户端创建,Server无法获取到。接下来通过代码展示正确的做法。
WifiManager 类的getChannel() 函数会创建一个AsyncChannel 以和WifiService 中的ServiceHandler 建立连接关系,并返回AsyncChannel 对象:
private synchronized AsyncChannel getChannel() { if (mAsyncChannel == null) { Messenger messenger = getWifiServiceMessenger(); //是Server 端的Handler 在Client 端的代表 if (messenger == null) { throw new IllegalStateException( "getWifiServiceMessenger() returned null! This is invalid."); } mAsyncChannel = new AsyncChannel(); //AsyncChannel 一般在Client 端创建 mConnected = new CountDownLatch(1); //ServiceHandler 是WifiManager 定义的内部类Handler Handler handler = new ServiceHandler(mLooper); //Client 端的Handler mAsyncChannel.connect(mContext, handler, messenger); //mContext 是Client 端的Context 对象 try { mConnected.await(); } catch (InterruptedException e) { Log.e(TAG, "interrupted wait at init"); } } return mAsyncChannel; }
getWifiServiceMessager() 函数,获取WifiService 端的Handler 引用,用于Client 与WifiService 建立AsyncChannel 通信:
public Messenger getWifiServiceMessenger() { try { return mService.getWifiServiceMessenger(); //返回的Messenger 对象包含WifiService 的Handler } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } }
mService 是IWifiManager 类对象,其实质是一个AIDL 接口,WifiServiceImpl 类继承自IWifiManager.Stub,所以getWifiServiceMessenger() 函数的实现在WifiServiceImpl.java 中:
/** * Get a reference to handler. This is used by a client to establish * an AsyncChannel communication with WifiService */ public Messenger getWifiServiceMessenger() { enforceAccessPermission(); //权限检查 enforceChangePermission(); return new Messenger(mClientHandler); //通过Messenger 封装了目标Handler }
connect() 函数将触发Client 端Handler(即ServiceHandler) 收到一个CMD_CHANNEL_HALF_CONNECTED 消息,由WifiManager 的ServiceHandler 处理:
private void dispatchMessageToListeners(Message message) { Object listener = removeListener(message.arg2); switch (message.what) { case AsyncChannel.CMD_CHANNEL_HALF_CONNECTED: if (message.arg1 == AsyncChannel.STATUS_SUCCESSFUL) { //半连接成功 mAsyncChannel.sendMessage(AsyncChannel.CMD_CHANNEL_FULL_CONNECTION); //向Server 端发送CMD_CHANNEL_FULL_CONNECTION } else { Log.e(TAG, "Failed to set up channel connection"); // This will cause all further async API calls on the WifiManager // to fail and throw an exception mAsyncChannel = null; } mConnected.countDown(); break;
case AsyncChannel.CMD_CHANNEL_FULLY_CONNECTED: //连接成功 // Ignore break; case AsyncChannel.CMD_CHANNEL_DISCONNECTED: //连接关闭 Log.e(TAG, "Channel connection lost"); // This will cause all further async API calls on the WifiManager // to fail and throw an exception mAsyncChannel = null; getLooper().quit(); //连接关闭,退出线程 break;
WifiServiceImpl.java 中定义ClientHandler,处理Client 端发送过来的消息:
/** * Handles client connections 处理Client 连接 */ private class ClientHandler extends Handler { @Override public void handleMessage(Message msg) { switch (msg.what) { case AsyncChannel.CMD_CHANNEL_HALF_CONNECTED: {
//处理因ac.connect调用而收到的CMD_CHANNEL_HALF_CONNECTED消息
//该消息携带了一个AsyncChannel 对象,即ac if (msg.arg1 == AsyncChannel.STATUS_SUCCESSFUL) { if (DBG) Slog.d(TAG, "New client listening to asynchronous messages"); // We track the clients by the Messenger // since it is expected to be always available mTrafficPoller.addClient(msg.replyTo); //WifiTrafficPoller 类
} break; } case AsyncChannel.CMD_CHANNEL_DISCONNECTED: { if (msg.arg1 == AsyncChannel.STATUS_SEND_UNSUCCESSFUL) { if (DBG) Slog.d(TAG, "Send failed, client connection lost"); } else { if (DBG) Slog.d(TAG, "Client connection lost with reason: " + msg.arg1); } mTrafficPoller.removeClient(msg.replyTo); break; } case AsyncChannel.CMD_CHANNEL_FULL_CONNECTION: { //Server 端先收到此消息 AsyncChannel ac = new AsyncChannel(); //新建一个AsyncChannel对象,调用它的connect()函数 ac.connect(mContext, this, msg.replyTo); //msg.replyTo 代表Client 端的Handler,即WifiManager 中ServiceHandler
//connect()函数将触发CMD_CHANNEL_HALF_CONNECTED消息被发送,而且该消息会携带对应的AsyncChannel 对象,即此次的ac break; }
WifiTrafficPoller 类的addClient() 方法:
void addClient(Messenger client) { Message.obtain(mTrafficHandler, ADD_CLIENT, client).sendToTarget(); }
ADD_CLIENT 消息由该类的内部类TrafficHandler 处理:
case ADD_CLIENT: mClients.add((Messenger) msg.obj); //保存上面的AsyncChannel 对象,用于向Client发送消息
break;
由于Server 端无法得到Client 端的AsyncChannel 对象,所以就新创建了一个AsyncChannel,并connect 到Client 端。
WifiService 构造函数分析
在上文看到WifiService 的构造函数主要创建一个WifiServiceImpl 对象,所以重点查看WifiServiceImpl 的构造函数:
public WifiServiceImpl(Context context) { HandlerThread wifiThread = new HandlerThread("WifiService"); wifiThread.start(); HandlerThread wifiStateMachineThread = new HandlerThread("WifiStateMachine"); wifiStateMachineThread.start(); mWifiStateMachine = new WifiStateMachine(mContext, mFacade, wifiStateMachineThread.getLooper(), mUserManager, mWifiInjector, new BackupManagerProxy(), mCountryCode); //创建一个WifiStateMachine对象 mWifiStateMachine.enableRssiPolling(true); //RSSI(信号接收强度)轮询机制
//WPAS支持的RSSI信息包括:接收信号强度、连接速度(link speed)、噪声强度(noise)和频率 mClientHandler = new ClientHandler(wifiThread.getLooper()); //用于AsyncChannel,其交互对象来自WifiManager mWifiStateMachineHandler = new WifiStateMachineHandler(wifiThread.getLooper()); //用于AsyncChannel,其交互对象来自WifiStateMachine }
标签:获取 ade noi service cte c++ 类 包括 add connected
原文地址:http://www.cnblogs.com/kaifyou/p/6184058.html