[Android]Android P(9) WIFI学习笔记 - Framework (2)

WIFI学习笔记 - Framework (2)

前言

  1. 更多细节详见上一篇
  2. 基于Android P源码学习;
  3. 代码片为了方便阅读段经过删、裁减,请以实际源码为准;

调用栈 - 关闭WIFI

与WIFI开启的调用入口一致,只是参数不同:

开启:
WifiManager.setWifiEnabled(true)
关闭:
WifiManager.setWifiEnabled(false)

因此从App调用到WifiServiceImpl这一部分链路是完全一致的;

从WifiController开始,两者执行逻辑分叉:

mWifiController.sendMessage(CMD_WIFI_TOGGLED)

同样,要确认这里的具体实现,就需要先确认现在工作的State:


通过上图以及代码确认,响应CMD_WIFI_TOGGLEDState只能是如下三种:

  • DeviceActiveState (由父状态StaEnabledState处理)
  • StaEnabledState
  • StaDisabledState

由于是关闭WIFI,因此当前WIFI状态一定不是StaDisabledState

DeviceActiveStateprocessMessage并未处理CMD_WIFI_TOGGLED,因此WifiController处理关闭WIFI流程时,响应CMD_WIFI_TOGGLED的只能是StaEnabledState中的processMessage

    class StaEnabledState extends State {
        ...
        @Override
        public boolean processMessage(Message msg) {
            switch (msg.what) {
                case CMD_WIFI_TOGGLED:
                    if (! mSettingsStore.isWifiToggleEnabled()) {
                        if (checkScanOnlyModeAvailable()) {
                            transitionTo(mStaDisabledWithScanState);
                        } else {
                            transitionTo(mStaDisabledState);
                        }
                    }
                    break;
                    ...
            }
            return HANDLED;
        }

WifiController初始状态时的判断逻辑一样,这里会视“WIFI始终扫描”选项是否开启来决定切换为StaDisabledWithScanState还是StaDisabledState

这里同理,以StaDisabledState为例继续;

不同于开启WIFI,关闭WIFI没有考虑到频繁开关导致的紊乱而添加doDeferDisable这样的方法,个人理解有如下两个原因:

  • 关闭后上层状态直接更新,底层关闭慢了也无所谓;
  • 下次开启时会做延时判断,因此关闭时没必要做;

在执行到StaDisabledStateenter()方法时:

    class StaDisabledState extends State {
        @Override
        public void enter() {
            mWifiStateMachinePrime.disableWifi();
            // Supplicant can't restart right away, so note the time we switched off
            mDisabledTimestamp = SystemClock.elapsedRealtime();
            mDeferredEnableSerialNumber++;
            mHaveDeferredEnable = false;
            mWifiStateMachine.clearANQPCache();
        }
        ...
    }

有两个关键调用:

  • mWifiStateMachinePrime.disableWifi();

  • mWifiStateMachine.clearANQPCache();

后者在Android P上是空实现,因此暂不讨论:

    public void clearANQPCache() {
        // TODO(b/31065385)
        // mWifiConfigManager.trimANQPCache(true);
    }

回到前者,其实现是发送消息给ModeStateMachine:

    public void disableWifi() {
        changeMode(ModeStateMachine.CMD_DISABLE_WIFI);
    }

这里再回顾下ModeStateMachine的三种平级状态:

  • ClientModeActiveState
  • ScanOnlyModeActiveState (暂不讨论)
  • WifiDisabledState

需要关闭WIFI的状态只会是ScanOnlyModeActiveStateWifiDisabledState,而这两个状态的processMessage()方法均是通过checkForAndHandleModeChange进行处理的:

        private boolean checkForAndHandleModeChange(Message message) {
            switch(message.what) {
                ...
                case ModeStateMachine.CMD_DISABLE_WIFI:
                    mModeStateMachine.transitionTo(mWifiDisabledState);
                    break;
                default:
                    return NOT_HANDLED;
            }
            return HANDLED;
        }

可见,ModeStateMachine会在处理消息时将状态切至WifiDisabledState,首先查看ScanOnlyModeActiveStateWifiDisabledStateexit()方法:

    public void exit() {
        super.exit();
        mListener = null;
    }

由于两者均继承自ModeActiveState(实际上WifiDisabledState也是继承的ModeActiveState,但其exit()被重写为空实现了),因此需要查看父类的exit()方法实现:

    public void exit() {
        if (mManager != null) {
            mManager.stop();
            mActiveModeManagers.remove(mManager);
        }
        updateBatteryStatsWifiState(false);
    }

此处会调用当前生效的接口ActiveModeManager的实现类的stop()方法,并将其从mActiveModeManagers移除
(这与开启WIFI是创建ClientModeManager,并将其添加到mActiveModeManagers相对应);

此处ActiveModeManager的子类实现只有两种可能:

  • ClientModeManager
    public void stop() {
        mExpectedStop = true;
        if (mClientInterfaceName != null) {
            if (mIfaceIsUp) {
                updateWifiState(WifiManager.WIFI_STATE_DISABLING,
                                WifiManager.WIFI_STATE_ENABLED);
            } else {
                updateWifiState(WifiManager.WIFI_STATE_DISABLING,
                                WifiManager.WIFI_STATE_ENABLING);
            }
        }
        mStateMachine.quitNow();
    }
  • ScanOnlyModeManager
    public void stop() {
        Log.d(TAG, " currentstate: " + getCurrentStateName());
        mExpectedStop = true;
        mStateMachine.quitNow();
    }

可见,无论是ClientModeManager,还是ScanOnlyModeManager,其stop()方法中始终调用了mStateMachine.quitNow()来停止其内部的状态机;

而当StateMachine的子类调用quitNow()时,会将内部状态切换至一个内部维护的QuittingState,此时必然会调用到当前状态的exit()方法;这里为了方便理解,仅列举ClientModeManager的情况,不讨论ScanOnlyModeManager

  • ClientModeStateMachine.StartedState
    public void exit() {
        //通知WifiStateMachine切换到DefaultState
        mWifiStateMachine.setOperationalMode(WifiStateMachine.DISABLED_MODE, null);

        if (mClientInterfaceName != null) {
            //关键代码,会调用到HAL移除对应iFace
            mWifiNative.teardownInterface(mClientInterfaceName);
            mClientInterfaceName = null;
            mIfaceIsUp = false;
        }

        //更新状态,并发送广播
        updateWifiState(WifiManager.WIFI_STATE_DISABLED,
                        WifiManager.WIFI_STATE_DISABLING);

        mStateMachine.quitNow();
    }

代码调用再次来到WifiNative,这里依旧不进一步深入了,会在HAL部分深入分析;

最后附上一副总结性质的时序图,其中部分非关键调用已经略去,关键调用加粗显示,蓝色框选的部分是与开启WIFI不同的区域;
在这里插入图片描述

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
Android开发教程及笔记-完整版.pdf》是一本关于Android开发的教程和笔记的完整版电子书。这本电子书主要介绍了Android开发所需的各种知识和技术,对于想要学习Android开发的人来说是一本非常有价值的资料。 这本电子书包含了Android开发的基础知识,如Android系统的介绍、Android开发环境的搭建以及常用开发工具的使用方法。同时,它也详细介绍了Android应用程序的开发流程,包括界面设计、布局管理、事件处理、数据库操作等方面的内容,使读者能够全面掌握Android应用程序的开发技巧。 此外,这本电子书还介绍了一些高级的Android开发技术,如网络编程、多媒体处理、传感器应用等方面的知识。通过学习这些高级技术,读者可以进一步提升自己的Android开发水平,设计出更加优秀和复杂的Android应用程序。 除了知识点的介绍之外,这本电子书还提供了大量的实例和代码,让读者能够通过实践来巩固所学知识。同时,它还给出了一些常见问题的解决方法和开发经验的分享,帮助读者更好地理解和应用所学的知识。 总之,《Android开发教程及笔记-完整版.pdf》是一本非常实用的Android开发学习资料,其全面而详细的内容将帮助读者系统地学习和掌握Android开发的技能,为实际项目的开发提供了很好的指导。无论是初学者还是有一定经验的开发者,都可以从中受益匪浅。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值