本文主要是介绍(七十三)WifiP2pSettings学习,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!
前言:最近在看WiFi相关的知识,发现WiFi direct是一种连接方式,WiFi直连(一种类似于蓝牙的传输应用)和WFD(Wifi Display)都会用到,先学习一下设置里比较熟悉的WifiP2pSettings。
1. WiFi p2p
WiFi P2P是Wi-Fi联盟推出的一项重要技术规范。 该规范的商品名为Wi-Fi Direct, 它支持多个Wi-Fi设备在没有AP的情况下相互连接。相对应的在连接同一个AP的情况下互相连接的叫做TDLS。WiFi联盟推出了名为TDLS(Tunneled Direct Link Setup,通道直接链路建立)的无线标准,这项标准允许两款设备通过WiFi网络进行点对点直连,与早起提倡的WiFi Direct相似,不过功能则更加完善。
2. Setting代码梳理
Settings里对应WiFi p2p主要就是WifiP2pSettings
路径:packages/apps/Settings/src/com/android/settings/wifi/p2p/WifiP2pSettings.java
2.1 onActivityCreated
WifiP2pSettings是个fragment,内部最先调用的是onActivityCreated。
@Overridepublic void onActivityCreated(Bundle savedInstanceState) {final Activity activity = getActivity();mWifiP2pManager = (WifiP2pManager) getSystemService(Context.WIFI_P2P_SERVICE);if (mWifiP2pManager != null) {mChannel = mWifiP2pManager.initialize(activity.getApplicationContext(),getActivity().getMainLooper(), null);if (mChannel == null) {//Failure to set up connectionLog.e(TAG, "Failed to set up connection with wifi p2p service");mWifiP2pManager = null;}} else {Log.e(TAG, "mWifiP2pManager is null !");}if (savedInstanceState != null && savedInstanceState.containsKey(SAVE_DIALOG_PEER)) {WifiP2pDevice device = savedInstanceState.getParcelable(SAVE_DIALOG_PEER);mSelectedWifiPeer = new WifiP2pPeer(getPrefContext(), device);}if (savedInstanceState != null && savedInstanceState.containsKey(SAVE_DEVICE_NAME)) {mSavedDeviceName = savedInstanceState.getString(SAVE_DEVICE_NAME);}if (savedInstanceState != null && savedInstanceState.containsKey(SAVE_SELECTED_GROUP)) {mSelectedGroupName = savedInstanceState.getString(SAVE_SELECTED_GROUP);}mRenameListener = new OnClickListener() {@Overridepublic void onClick(DialogInterface dialog, int which) {if (which == DialogInterface.BUTTON_POSITIVE) {if (mWifiP2pManager != null) {String name = mDeviceNameText.getText().toString();if (name != null) {for (int i = 0; i < name.length(); i++) {char cur = name.charAt(i);if(!Character.isDigit(cur) && !Character.isLetter(cur)&& cur != '-' && cur != '_' && cur != ' ') {Toast.makeText(getActivity(),R.string.wifi_p2p_failed_rename_message,Toast.LENGTH_LONG).show();return;}}}mWifiP2pManager.setDeviceName(mChannel,mDeviceNameText.getText().toString(),new WifiP2pManager.ActionListener() {public void onSuccess() {if (DBG) Log.d(TAG, " device rename success");}public void onFailure(int reason) {Toast.makeText(getActivity(),R.string.wifi_p2p_failed_rename_message,Toast.LENGTH_LONG).show();}});}}}};//disconnect dialog listenermDisconnectListener = new OnClickListener() {@Overridepublic void onClick(DialogInterface dialog, int which) {if (which == DialogInterface.BUTTON_POSITIVE) {if (mWifiP2pManager != null) {mWifiP2pManager.removeGroup(mChannel, new WifiP2pManager.ActionListener() {public void onSuccess() {if (DBG) Log.d(TAG, " remove group success");}public void onFailure(int reason) {if (DBG) Log.d(TAG, " remove group fail " + reason);}});}}}};//cancel connect dialog listenermCancelConnectListener = new OnClickListener() {@Overridepublic void onClick(DialogInterface dialog, int which) {if (which == DialogInterface.BUTTON_POSITIVE) {if (mWifiP2pManager != null) {mWifiP2pManager.cancelConnect(mChannel,new WifiP2pManager.ActionListener() {public void onSuccess() {if (DBG) Log.d(TAG, " cancel connect success");}public void onFailure(int reason) {if (DBG) Log.d(TAG, " cancel connect fail " + reason);}});}}}};//delete persistent group dialog listenermDeleteGroupListener = new OnClickListener() {@Overridepublic void onClick(DialogInterface dialog, int which) {if (which == DialogInterface.BUTTON_POSITIVE) {if (mWifiP2pManager != null) {if (mSelectedGroup != null) {if (DBG) Log.d(TAG, " deleting group " + mSelectedGroup.getGroupName());mWifiP2pManager.deletePersistentGroup(mChannel,mSelectedGroup.getNetworkId(),new WifiP2pManager.ActionListener() {public void onSuccess() {if (DBG) Log.d(TAG, " delete group success");}public void onFailure(int reason) {if (DBG) Log.d(TAG, " delete group fail " + reason);}});mSelectedGroup = null;} else {if (DBG) Log.w(TAG, " No selected group to delete!");}}} else if (which == DialogInterface.BUTTON_NEGATIVE) {if (DBG) {Log.d(TAG, " forgetting selected group " + mSelectedGroup.getGroupName());}mSelectedGroup = null;}}};super.onActivityCreated(savedInstanceState);}
主要干了两个事:
1.初始化了
mChannel = mWifiP2pManager.initialize(activity.getApplicationContext(),getActivity().getMainLooper(), null);
2.初始化了四个listener,分别是mRenameListener mDisconnectListener mCancelConnectListener mDeleteGroupListener
这里主要继续看下WifiP2pManager.initialize的方法做了什么操作。
WifiP2pManager
/*** Registers the application with the Wi-Fi framework. This function* must be the first to be called before any p2p operations are performed.** @param srcContext is the context of the source* @param srcLooper is the Looper on which the callbacks are receivied* @param listener for callback at loss of framework communication. Can be null.* @return Channel instance that is necessary for performing any further p2p operations*/public Channel initialize(Context srcContext, Looper srcLooper, ChannelListener listener) {Binder binder = new Binder();Channel channel = initalizeChannel(srcContext, srcLooper, listener, getMessenger(binder),binder);return channel;}
private Channel initalizeChannel(Context srcContext, Looper srcLooper, ChannelListener listener,Messenger messenger, Binder binder) {if (messenger == null) return null;Channel c = new Channel(srcContext, srcLooper, listener, binder, this);if (c.mAsyncChannel.connectSync(srcContext, c.mHandler, messenger)== AsyncChannel.STATUS_SUCCESSFUL) {return c;} else {c.close();return null;}}
/*** Get a reference to WifiP2pService handler. This is used to establish* an AsyncChannel communication with WifiService** @param binder A binder for the service to associate with this client.** @return Messenger pointing to the WifiP2pService handler* @hide*/public Messenger getMessenger(Binder binder) {try {return mService.getMessenger(binder);} catch (RemoteException e) {throw e.rethrowFromSystemServer();}}
这里用到了AsyncChannel,简单来说就是将WifiP2pManager$Channel$P2pHandler和WifiP2pServiceImpl$ClientHandler连接上,以便后续的message通讯。
2.2 onResume
@Overridepublic void onResume() {super.onResume();mIntentFilter.addAction(WifiP2pManager.WIFI_P2P_STATE_CHANGED_ACTION);mIntentFilter.addAction(WifiP2pManager.WIFI_P2P_PEERS_CHANGED_ACTION);mIntentFilter.addAction(WifiP2pManager.WIFI_P2P_CONNECTION_CHANGED_ACTION);mIntentFilter.addAction(WifiP2pManager.WIFI_P2P_THIS_DEVICE_CHANGED_ACTION);mIntentFilter.addAction(WifiP2pManager.WIFI_P2P_DISCOVERY_CHANGED_ACTION);mIntentFilter.addAction(WifiP2pManager.WIFI_P2P_PERSISTENT_GROUPS_CHANGED_ACTION);final PreferenceScreen preferenceScreen = getPreferenceScreen();getActivity().registerReceiver(mReceiver, mIntentFilter);if (mWifiP2pManager != null) {mWifiP2pManager.requestPeers(mChannel, WifiP2pSettings.this);}}
做了两件事情
1.注册了6个广播的监听器
2.调用WifiP2pManager.requestPeers来获取周围可连接设备,填充UI。
2.2.1 startSearch
广播接收器代码如下:
private final BroadcastReceiver mReceiver = new BroadcastReceiver() {@Overridepublic void onReceive(Context context, Intent intent) {String action = intent.getAction();if (WifiP2pManager.WIFI_P2P_STATE_CHANGED_ACTION.equals(action)) {mWifiP2pEnabled = intent.getIntExtra(WifiP2pManager.EXTRA_WIFI_STATE,WifiP2pManager.WIFI_P2P_STATE_DISABLED) == WifiP2pManager.WIFI_P2P_STATE_ENABLED;handleP2pStateChanged();} else if (WifiP2pManager.WIFI_P2P_PEERS_CHANGED_ACTION.equals(action)) {mPeers = (WifiP2pDeviceList) intent.getParcelableExtra(WifiP2pManager.EXTRA_P2P_DEVICE_LIST);handlePeersChanged();} else if (WifiP2pManager.WIFI_P2P_CONNECTION_CHANGED_ACTION.equals(action)) {if (mWifiP2pManager == null) return;NetworkInfo networkInfo = (NetworkInfo) intent.getParcelableExtra(WifiP2pManager.EXTRA_NETWORK_INFO);WifiP2pInfo wifip2pinfo = (WifiP2pInfo) intent.getParcelableExtra(WifiP2pManager.EXTRA_WIFI_P2P_INFO);if (networkInfo.isConnected()) {if (DBG) Log.d(TAG, "Connected");} else if (mLastGroupFormed != true) {//start a search when we are disconnected//but not on group removed broadcast eventstartSearch();}mLastGroupFormed = wifip2pinfo.groupFormed;} else if (WifiP2pManager.WIFI_P2P_THIS_DEVICE_CHANGED_ACTION.equals(action)) {mThisDevice = (WifiP2pDevice) intent.getParcelableExtra(WifiP2pManager.EXTRA_WIFI_P2P_DEVICE);if (DBG) Log.d(TAG, "Update device info: " + mThisDevice);mThisDevicePreferenceController.updateDeviceName(mThisDevice);} else if (WifiP2pManager.WIFI_P2P_DISCOVERY_CHANGED_ACTION.equals(action)) {int discoveryState = intent.getIntExtra(WifiP2pManager.EXTRA_DISCOVERY_STATE,WifiP2pManager.WIFI_P2P_DISCOVERY_STOPPED);if (DBG) Log.d(TAG, "Discovery state changed: " + discoveryState);if (discoveryState == WifiP2pManager.WIFI_P2P_DISCOVERY_STARTED) {updateSearchMenu(true);} else {updateSearchMenu(false);}} else if (WifiP2pManager.WIFI_P2P_PERSISTENT_GROUPS_CHANGED_ACTION.equals(action)) {if (mWifiP2pManager != null) {mWifiP2pManager.requestPersistentGroupInfo(mChannel, WifiP2pSettings.this);}}}};
发现在接收到WifiP2pManager.WIFI_P2P_CONNECTION_CHANGED_ACTION消息的时候会调用startSearch方法
private void startSearch() {if (mWifiP2pManager != null && !mWifiP2pSearching) {mWifiP2pManager.discoverPeers(mChannel, new WifiP2pManager.ActionListener() {public void onSuccess() {}public void onFailure(int reason) {if (DBG) Log.d(TAG, " discover fail " + reason);}});}}
WifiP2pManager
/*** Initiate peer discovery. A discovery process involves scanning for available Wi-Fi peers* for the purpose of establishing a connection.** <p> The function call immediately returns after sending a discovery request* to the framework. The application is notified of a success or failure to initiate* discovery through listener callbacks {@link ActionListener#onSuccess} or* {@link ActionListener#onFailure}.** <p> The discovery remains active until a connection is initiated or* a p2p group is formed. Register for {@link #WIFI_P2P_PEERS_CHANGED_ACTION} intent to* determine when the framework notifies of a change as peers are discovered.** <p> Upon receiving a {@link #WIFI_P2P_PEERS_CHANGED_ACTION} intent, an application* can request for the list of peers using {@link #requestPeers}.** @param c is the channel created at {@link #initialize}* @param listener for callbacks on success or failure. Can be null.*/public void discoverPeers(Channel c, ActionListener listener) {checkChannel(c);c.mAsyncChannel.sendMessage(DISCOVER_PEERS, 0, c.putListener(listener));}
看API注释里讲
- 搜索会持续到连接或者p2p group 建立
- 当监听到WIFI_P2P_PEERS_CHANGED_ACTION消息时,应用可以通过requestPeers请求peers列表。
观察到WifiP2pSettings里有监听这个消息做mPeers和界面的刷新处理。
WifiP2pSettings:
} else if (WifiP2pManager.WIFI_P2P_PEERS_CHANGED_ACTION.equals(action)) {mPeers = (WifiP2pDeviceList) intent.getParcelableExtra(WifiP2pManager.EXTRA_P2P_DEVICE_LIST);handlePeersChanged();
之前梳理过了这个DISCOVER_PEERS消息会发送给WifiP2pServiceImpl来继续处理。
WifiP2pServiceImpl:
/*** Handles client connections*/private class ClientHandler extends WifiHandler {ClientHandler(String tag, android.os.Looper looper) {super(tag, looper);}@Overridepublic void handleMessage(Message msg) {super.handleMessage(msg);switch (msg.what) {case WifiP2pManager.SET_DEVICE_NAME:case WifiP2pManager.SET_WFD_INFO:case WifiP2pManager.DISCOVER_PEERS:case WifiP2pManager.STOP_DISCOVERY:case WifiP2pManager.CONNECT:case WifiP2pManager.CANCEL_CONNECT:case WifiP2pManager.CREATE_GROUP:case WifiP2pManager.REMOVE_GROUP:case WifiP2pManager.START_LISTEN:case WifiP2pManager.STOP_LISTEN:case WifiP2pManager.SET_CHANNEL:case WifiP2pManager.START_WPS:case WifiP2pManager.ADD_LOCAL_SERVICE:case WifiP2pManager.REMOVE_LOCAL_SERVICE:case WifiP2pManager.CLEAR_LOCAL_SERVICES:case WifiP2pManager.DISCOVER_SERVICES:case WifiP2pManager.ADD_SERVICE_REQUEST:case WifiP2pManager.REMOVE_SERVICE_REQUEST:case WifiP2pManager.CLEAR_SERVICE_REQUESTS:case WifiP2pManager.REQUEST_PEERS:case WifiP2pManager.REQUEST_CONNECTION_INFO:case WifiP2pManager.REQUEST_GROUP_INFO:case WifiP2pManager.DELETE_PERSISTENT_GROUP:case WifiP2pManager.REQUEST_PERSISTENT_GROUP_INFO:mP2pStateMachine.sendMessage(Message.obtain(msg));break;default:Slog.d(TAG, "ClientHandler.handleMessage ignoring msg=" + msg);break;}}}
熟悉的状态机P2pEnabledState会做如下处理:
case WifiP2pManager.DISCOVER_PEERS:if (mDiscoveryBlocked) {replyToMessage(message, WifiP2pManager.DISCOVER_PEERS_FAILED,WifiP2pManager.BUSY);break;}// do not send service discovery request while normal find operation.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;
// Set a two minute discover timeout to avoid STA scans from being blockedprivate static final int DISCOVER_TIMEOUT_S = 120;
有个120s的timeout限制。
WifiNative:
/*** Initiate a P2P service discovery with a (optional) timeout.** @param timeout Max time to be spent is peforming discovery.* Set to 0 to indefinely continue discovery untill and explicit* |stopFind| is sent.* @return boolean value indicating whether operation was successful.*/public boolean p2pFind(int timeout) {return mSupplicantP2pIfaceHal.find(timeout);}
SupplicantP2pIfaceHal:
/*** Initiate a P2P service discovery with a (optional) timeout.** @param timeout Max time to be spent is peforming discovery.* Set to 0 to indefinely continue discovery untill and explicit* |stopFind| is sent.* @return boolean value indicating whether operation was successful.*/public boolean find(int timeout) {synchronized (mLock) {if (!checkSupplicantP2pIfaceAndLogFailure("find")) return false;if (timeout < 0) {Log.e(TAG, "Invalid timeout value: " + timeout);return false;}SupplicantResult<Void> result = new SupplicantResult("find(" + timeout + ")");try {result.setResult(mISupplicantP2pIface.find(timeout));} catch (RemoteException e) {Log.e(TAG, "ISupplicantP2pIface exception: " + e);supplicantServiceDiedHandler();}return result.isSuccess();}}
2.2.2 requestPeers
WifiP2pManager:
/*** Request the current list of peers.** @param c is the channel created at {@link #initialize}* @param listener for callback when peer list is available. Can be null.*/public void requestPeers(Channel c, PeerListListener listener) {checkChannel(c);Bundle callingPackage = new Bundle();callingPackage.putString(CALLING_PACKAGE, c.mContext.getOpPackageName());c.mAsyncChannel.sendMessage(REQUEST_PEERS, 0, c.putListener(listener),callingPackage);}
WifiP2pServiceImpl:
DefaultState会处理该消息,并回复给WifiP2pManager
case WifiP2pManager.REQUEST_PEERS:replyToMessage(message, WifiP2pManager.RESPONSE_PEERS,getPeers((Bundle) message.obj, message.sendingUid));break;
WifiManager:
case RESPONSE_PEERS:WifiP2pDeviceList peers = (WifiP2pDeviceList) message.obj;if (listener != null) {((PeerListListener) listener).onPeersAvailable(peers);}break;
WifiP2pSettings:
@Overridepublic void onPeersAvailable(WifiP2pDeviceList peers) {if (DBG) Log.d(TAG, "Requested peers are available");mPeers = peers;handlePeersChanged();}
private void handlePeersChanged() {mPeerCategoryController.removeAllChildren();mConnectedDevices = 0;if (DBG) Log.d(TAG, "List of available peers");for (WifiP2pDevice peer: mPeers.getDeviceList()) {if (DBG) Log.d(TAG, "-> " + peer);mPeerCategoryController.addChild(new WifiP2pPeer(getPrefContext(), peer));if (peer.status == WifiP2pDevice.CONNECTED) mConnectedDevices++;}if (DBG) Log.d(TAG, " mConnectedDevices " + mConnectedDevices);}
简单来看调用framework和回调获取扫描结果流程已经借宿了,回过头来看下WifiP2pServiceImpl的getPeers方法:
WifiP2pServiceImpl
case WifiP2pManager.REQUEST_PEERS:replyToMessage(message, WifiP2pManager.RESPONSE_PEERS,getPeers((Bundle) message.obj, message.sendingUid));break;
/*** Enforces permissions on the caller who is requesting for P2p Peers* @param pkg Bundle containing the calling package string* @param uid of the caller* @return WifiP2pDeviceList the peer list*/private WifiP2pDeviceList getPeers(Bundle pkg, int uid) {String pkgName = pkg.getString(WifiP2pManager.CALLING_PACKAGE);boolean scanPermission = false;WifiPermissionsUtil wifiPermissionsUtil;// getPeers() is guaranteed to be invoked after Wifi Service is up// This ensures getInstance() will return a non-null object nowif (mWifiInjector == null) {mWifiInjector = WifiInjector.getInstance();}wifiPermissionsUtil = mWifiInjector.getWifiPermissionsUtil();// Minimum Version to enforce location permission is O or latertry {scanPermission = wifiPermissionsUtil.canAccessScanResults(pkgName, uid,Build.VERSION_CODES.O);} catch (SecurityException e) {Log.e(TAG, "Security Exception, cannot access peer list");}if (scanPermission) {return new WifiP2pDeviceList(mPeers);} else {return new WifiP2pDeviceList();}}}
这个方法只是校验了下权限,然后将mPeers封装出来了,mPeers应该是之前扫描结果封装起来的。
而mPeers的加载成员只有调用如下方法:
WifiP2pDeviceList:
/** Only updates details fetched from the supplicant @hide */public void updateSupplicantDetails(WifiP2pDevice device) {validateDevice(device);WifiP2pDevice d = mDevices.get(device.deviceAddress);if (d != null) {d.deviceName = device.deviceName;d.primaryDeviceType = device.primaryDeviceType;d.secondaryDeviceType = device.secondaryDeviceType;d.wpsConfigMethodsSupported = device.wpsConfigMethodsSupported;d.deviceCapability = device.deviceCapability;d.groupCapability = device.groupCapability;d.wfdInfo = device.wfdInfo;return;}//Not found, add a new onemDevices.put(device.deviceAddress, device);}
只有在WifiP2pServiceImpl$P2pEnabledState状态处理P2P_DEVICE_FOUND_EVENT的时候加载
case WifiP2pMonitor.P2P_DEVICE_FOUND_EVENT:if (message.obj == null) {Log.e(TAG, "Illegal argument(s)");break;}WifiP2pDevice device = (WifiP2pDevice) message.obj;if (mThisDevice.deviceAddress.equals(device.deviceAddress)) break;mPeers.updateSupplicantDetails(device);sendPeersChangedBroadcast();break;
这个消息应该是WifiMonitor监听到supplicant返回来告知WifiP2pServiceImpl$P2pEnabledState处理的。
mWifiMonitor.registerHandler(interfaceName,WifiP2pMonitor.P2P_DEVICE_FOUND_EVENT, getHandler());
2.3 connect
看下wifi p2p connect流程
WifiP2pSettings:
@Overridepublic boolean onPreferenceTreeClick(Preference preference) {if (preference instanceof WifiP2pPeer) {mSelectedWifiPeer = (WifiP2pPeer) preference;if (mSelectedWifiPeer.device.status == WifiP2pDevice.CONNECTED) {showDialog(DIALOG_DISCONNECT);} else if (mSelectedWifiPeer.device.status == WifiP2pDevice.INVITED) {showDialog(DIALOG_CANCEL_CONNECT);} else {WifiP2pConfig config = new WifiP2pConfig();config.deviceAddress = mSelectedWifiPeer.device.deviceAddress;int forceWps = SystemProperties.getInt("wifidirect.wps", -1);if (forceWps != -1) {config.wps.setup = forceWps;} else {if (mSelectedWifiPeer.device.wpsPbcSupported()) {config.wps.setup = WpsInfo.PBC;} else if (mSelectedWifiPeer.device.wpsKeypadSupported()) {config.wps.setup = WpsInfo.KEYPAD;} else {config.wps.setup = WpsInfo.DISPLAY;}}mWifiP2pManager.connect(mChannel, config,new WifiP2pManager.ActionListener() {public void onSuccess() {if (DBG) Log.d(TAG, " connect success");}public void onFailure(int reason) {Log.e(TAG, " connect fail " + reason);Toast.makeText(getActivity(),R.string.wifi_p2p_failed_connect_message,Toast.LENGTH_SHORT).show();}});}} else if (preference instanceof WifiP2pPersistentGroup) {mSelectedGroup = (WifiP2pPersistentGroup) preference;showDialog(DIALOG_DELETE_GROUP);}return super.onPreferenceTreeClick(preference);}
WifiP2pManager:
/*** Start a p2p connection to a device with the specified configuration.** <p> The function call immediately returns after sending a connection request* to the framework. The application is notified of a success or failure to initiate* connect through listener callbacks {@link ActionListener#onSuccess} or* {@link ActionListener#onFailure}.** <p> Register for {@link #WIFI_P2P_CONNECTION_CHANGED_ACTION} intent to* determine when the framework notifies of a change in connectivity.** <p> If the current device is not part of a p2p group, a connect request initiates* a group negotiation with the peer.** <p> If the current device is part of an existing p2p group or has created* a p2p group with {@link #createGroup}, an invitation to join the group is sent to* the peer device.** @param c is the channel created at {@link #initialize}* @param config options as described in {@link WifiP2pConfig} class* @param listener for callbacks on success or failure. Can be null.*/public void connect(Channel c, WifiP2pConfig config, ActionListener listener) {checkChannel(c);checkP2pConfig(config);c.mAsyncChannel.sendMessage(CONNECT, 0, c.putListener(listener), config);}
WifiP2pServiceImpl$GroupCreatedState(看InactiveState也会处理)
case WifiP2pManager.CONNECT:WifiP2pConfig config = (WifiP2pConfig) message.obj;if (isConfigInvalid(config)) {loge("Dropping connect request " + config);replyToMessage(message, WifiP2pManager.CONNECT_FAILED);break;}logd("Inviting device : " + config.deviceAddress);mSavedPeerConfig = config;if (mWifiNative.p2pInvite(mGroup, config.deviceAddress)) {mPeers.updateStatus(config.deviceAddress, WifiP2pDevice.INVITED);sendPeersChangedBroadcast();replyToMessage(message, WifiP2pManager.CONNECT_SUCCEEDED);} else {replyToMessage(message, WifiP2pManager.CONNECT_FAILED,WifiP2pManager.ERROR);}// TODO: figure out updating the status to declined// when invitation is rejectedbreak;
WifiNative
/*** Invite a device to a persistent group.* If the peer device is the group owner of the persistent group, the peer* parameter is not needed. Otherwise it is used to specify which* device to invite. |goDeviceAddress| parameter may be used to override* the group owner device address for Invitation Request should it not be* known for some reason (this should not be needed in most cases).** @param group Group object to use.* @param deviceAddress MAC address of the device to invite.** @return boolean value indicating whether operation was successful.*/public boolean p2pInvite(WifiP2pGroup group, String deviceAddress) {return mSupplicantP2pIfaceHal.invite(group, deviceAddress);}
SupplicantP2pIfaceHal
/*** Invite a device to a persistent group.* If the peer device is the group owner of the persistent group, the peer* parameter is not needed. Otherwise it is used to specify which* device to invite. |goDeviceAddress| parameter may be used to override* the group owner device address for Invitation Request should it not be* known for some reason (this should not be needed in most cases).** @param group Group object to use.* @param peerAddress MAC address of the device to invite.** @return boolean value indicating whether operation was successful.*/public boolean invite(WifiP2pGroup group, String peerAddress) {if (TextUtils.isEmpty(peerAddress)) return false;synchronized (mLock) {if (!checkSupplicantP2pIfaceAndLogFailure("invite")) return false;if (group == null) {Log.e(TAG, "Cannot invite to null group.");return false;}if (group.getOwner() == null) {Log.e(TAG, "Cannot invite to group with null owner.");return false;}if (group.getOwner().deviceAddress == null) {Log.e(TAG, "Group owner has no mac address.");return false;}byte[] ownerMacAddress = null;try {ownerMacAddress = NativeUtil.macAddressToByteArray(group.getOwner().deviceAddress);} catch (Exception e) {Log.e(TAG, "Group owner mac address parse error.", e);return false;}if (peerAddress == null) {Log.e(TAG, "Cannot parse peer mac address.");return false;}byte[] peerMacAddress;try {peerMacAddress = NativeUtil.macAddressToByteArray(peerAddress);} catch (Exception e) {Log.e(TAG, "Peer mac address parse error.", e);return false;}SupplicantResult<Void> result = new SupplicantResult("invite(" + group.getInterface() + ", " + group.getOwner().deviceAddress+ ", " + peerAddress + ")");try {result.setResult(mISupplicantP2pIface.invite(group.getInterface(), ownerMacAddress, peerMacAddress));} catch (RemoteException e) {Log.e(TAG, "ISupplicantP2pIface exception: " + e);supplicantServiceDiedHandler();}return result.isSuccess();}}
先梳理到这。。。
3.总结
这篇关于(七十三)WifiP2pSettings学习的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!