我们先来看一下WifiDisplay的代码,先从UI看起。 WifiDisplay是在Wifi P2P的基础上发展而来的,他的功能实现也离不开P2P。所以在WifiDisplaySettings的onCreate中,就先初始化了WifiP2P。 /packages/apps/Settings/src/com/android/settings/wfd/WifiDisplaySettings.java
@Override public void onCreate(Bundle icicle) { super.onCreate(icicle); final Context context = getActivity(); mRouter = (MediaRouter) context.getSystemService(Context.MEDIA_ROUTER_SERVICE); mDisplayManager = (DisplayManager) context.getSystemService(Context.DISPLAY_SERVICE); mWifiP2pManager = (WifiP2pManager) context.getSystemService(Context.WIFI_P2P_SERVICE); mWifiP2pChannel = mWifiP2pManager.initialize(context, Looper.getMainLooper(), null); addPreferencesFromResource(R.xml.wifi_display_settings); setHasOptionsMenu(true); }
然后找到开启投屏的开关组件,check以后,修改数据库相关参数WIFI_DISPLAY_ON,从false置为true。
@Override public boolean onOptionsItemSelected(MenuItem item) { switch (item.getItemId()) { case MENU_ID_ENABLE_WIFI_DISPLAY: mWifiDisplayOnSetting = !item.isChecked(); item.setChecked(mWifiDisplayOnSetting); Settings.Global.putInt(getContentResolver(), Settings.Global.WIFI_DISPLAY_ON, mWifiDisplayOnSetting ? 1 : 0); return true; } return super.onOptionsItemSelected(item); }
WifiDisplayController中从数据库查询WIFI_DISPLAY_ON参数,如果为true,表示开启WifiDisplay,然后开始一系列操作。 /frameworks/base/services/core/java/com/android/server/display/WifiDisplayController.java
private void updateSettings() { final ContentResolver resolver = mContext.getContentResolver(); mWifiDisplayOnSetting = Settings.Global.getInt(resolver, Settings.Global.WIFI_DISPLAY_ON, 0) != 0;
首先是修改状态,然后修改wfdinfo的相关配置信息。 WifiP2PManager也要进行相关配置,主要是setWFDInfo。
private void updateWfdEnableState() { if (mWifiDisplayOnSetting && mWifiP2pEnabled) { // WFD should be enabled. if (!mWfdEnabled && !mWfdEnabling) { mWfdEnabling = true; WifiP2pWfdInfo wfdInfo = new WifiP2pWfdInfo(); wfdInfo.setWfdEnabled(true); wfdInfo.setDeviceType(WifiP2pWfdInfo.WFD_SOURCE); wfdInfo.setSessionAvailable(true); wfdInfo.setControlPort(DEFAULT_CONTROL_PORT); wfdInfo.setMaxThroughput(MAX_THROUGHPUT); mWifiP2pManager.setWFDInfo(mWifiP2pChannel, wfdInfo, new ActionListener() { @Override public void onSuccess() { if (DEBUG) { Slog.d(TAG, "Successfully set WFD info."); } if (mWfdEnabling) { mWfdEnabling = false; mWfdEnabled = true; reportFeatureState(); updateScanState(); } }
我们看setWFDInfo函数,主要是调用WifiP2pServiceImpl的checkConfigureWifiDisplayPermission方法。
public void setWFDInfo( Channel c, WifiP2pWfdInfo wfdInfo, ActionListener listener) { checkChannel(c); try { mService.checkConfigureWifiDisplayPermission(); } catch (RemoteException e) { e.rethrowFromSystemServer(); } c.mAsyncChannel.sendMessage(SET_WFD_INFO, 0, c.putListener(listener), wfdInfo); }
这里是检测wfd有没有相关的权限。 /frameworks/opt/net/wifi/service/java/com/android/server/wifi/p2p/WifiP2pServiceImpl.java
@Override public void checkConfigureWifiDisplayPermission() { if (!getWfdPermission(Binder.getCallingUid())) { throw new SecurityException("Wifi Display Permission denied for uid = " + Binder.getCallingUid()); } }
然后执行完以后就执行到updateScanState,就到扫描阶段了 /frameworks/base/services/core/java/com/android/server/display/WifiDisplayController.java
private void updateScanState() { if (mScanRequested && mWfdEnabled && mDesiredDevice == null) { if (!mDiscoverPeersInProgress) { Slog.i(TAG, "Starting Wifi display scan."); mDiscoverPeersInProgress = true; handleScanStarted(); tryDiscoverPeers(); } } else { if (mDiscoverPeersInProgress) { // Cancel automatic retry right away. mHandler.removeCallbacks(mDiscoverPeers); // Defer actually stopping discovery if we have a connection attempt in progress. // The wifi display connection attempt often fails if we are not in discovery // mode. So we allow discovery to continue until we give up trying to connect. if (mDesiredDevice == null || mDesiredDevice == mConnectedDevice) { Slog.i(TAG, "Stopping Wifi display scan."); mDiscoverPeersInProgress = false; stopPeerDiscovery(); handleScanFinished(); } } } }
本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。
我来说两句