专栏首页程序猿的那点事WifiDisplay开启流程

WifiDisplay开启流程

我们先来看一下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();
                }
            }
        }
    }

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • Android GPS学习 (一) :GPS 启动流程

    packages/apps/Settings/src/com/android/settings/location/LocationSwitchBarContro...

    用户7557625
  • Android开发必须知道的adb命令大全

    用户7557625
  • LocalOnlyHotspot学习总结

    前言:最近项目用到了LocalOnlyHotspot,做Wifi半年了也是第一次接触,在这里把最近俩周的学习内容做个总结。

    用户7557625
  • vue-cli3.0与vant的引入

    Ewall
  • css实现页面加载动画

    小小咸鱼YwY
  • Memcache集群环境下缓存解决方案

    版权声明:本文为博主原创文章,遵循 CC 4.0 by-sa 版权协议,转载请附上原文出处链接和本声明。

    奋飛
  • ZooKeeper 笔记(6) 分布式锁

      目前分布式锁,比较成熟、主流的方案有基于redis及基于zookeeper的二种方案。   大体来讲,基于redis的分布式锁核心指令为SETNX,即如果目...

    菩提树下的杨过
  • 面试官喜欢问的Java编译期与运行期问题总结全了

    不知大家有没有思考过,当我们使用IDE写了一个Demo类,并执行main函数打印 hello world时都经历了哪些流程么?

    业余草
  • memcached安装及.NET中的Memcached.ClientLibrary使用详解

    序言 吹吹牛逼先,借我你的20分钟,保证你在.net中使用memcached缓存数据,畅通无阻,提升数据读取效率,分担数据库压力,便不在话下。 本篇主要说下:m...

    逸鹏
  • 深入Python多进程编程基础

    多进程编程知识是Python程序员进阶高级的必备知识点,我们平时习惯了使用multiprocessing库来操纵多进程,但是并不知道它的具体实现原理。下面我对多...

    老钱

扫码关注云+社区

领取腾讯云代金券