我是如何修改Google留下的BUG

How did i fixed the Google's bug ?

Posted by Roger on April 2, 2015

写下这个标题我脸都红了..

不来点干货怎能留下你们呢,客官请留步,好酒好肉马上来。

QA大大们提了个BUG:打开WIFI条件下,疯狂点击便携式热点按钮,接着按钮就再也点不动了。

跟进代码一看,哎呀我去,没人改过,这是google写的。在最新的5.0系统中测试,一样存在这个问题。卧槽,QA太牛了,google好几年没测出来的BUG你都能发现。

好吧,接下来又是苦逼的求知之旅。

根据“便携式 WLAN 热点” 全文搜索找到对应的资源

"便携式 WLAN 热点"

再根据 name=”wifi_tether_checkbox_text” 找到对应的xml:tether_prefs.xml,看来这个xml就是我们的页面了,再全局搜索tether_prefs 定位到 TetherSettings。很不错,已经摸到大腿了。接下来都是java那就好办了,两三步定位到代码 425 行

public boolean onPreferenceChange(Preference preference, Object value) {
        boolean enable = (Boolean) value;
        if (enable) {
                startProvisioningIfNecessary(WIFI_TETHERING);
        } else {
                mWifiApEnabler.setSoftapEnabled(false);
        }
        return false;
}

每次点击就是调用这个方法。好的,继续跟进,发现设置热点打开关闭主要是通过 WifiApEnabler 这个类中的 setSoftapEnabled()这个方法。从上面可以看出来,点击关闭的时候直接就调用  mWifiApEnabler.setSoftapEnabled(false); ,打开的时候实际也是调用这个方法,详细代码不多说。方法的代码如下,关键部分请看注释

public void setSoftapEnabled(boolean enable) {
        final ContentResolver cr = mContext.getContentResolver();
        /**
        * Disable Wifi if enabling tethering
        */
        int wifiState = mWifiManager.getWifiState();//获取wifi状态,因为打开热点是要关闭wifi的
        if (enable && ((wifiState == WifiManager.WIFI_STATE_ENABLING) ||
        (wifiState == WifiManager.WIFI_STATE_ENABLED))) {//若wifi为打开或打开中状态
                mWifiManager.setWifiEnabled(false);//关闭wifi
                Settings.Global.putInt(cr, Settings.Global.WIFI_SAVED_STATE, 1);//记录WIFI的状态
        }

        if (mWifiManager.setWifiApEnabled(null, enable)) {//判断是否能打开热点(飞行模式不能打开)
        /* Disable here, enabled on receiving success broadcast */
                mCheckBox.setEnabled(false);//设置不能点击,在接受到热点打开后设置可以点击,具体看源码handleWifiApStateChanged()方法
        } else {
                mCheckBox.setSummary(R.string.wifi_error);
        }

        /**
        * If needed, restore Wifi on tether disable
        */
        if (!enable) {//关闭热点
                int wifiSavedState = 0;
                try {
                        wifiSavedState = Settings.Global.getInt(cr, Settings.Global.WIFI_SAVED_STATE);//获得打开热点前wifi的状态
                } catch (Settings.SettingNotFoundException e) {
                        ;
                }
                if (wifiSavedState == 1) {
                        mWifiManager.setWifiEnabled(true);//打开wifi
                        Settings.Global.putInt(cr, Settings.Global.WIFI_SAVED_STATE, 0);//状态恢复
                }
        }
}

乍一看,代码没有任何逻辑问题,那为何疯狂点击后会无法再次点击呢?这是这个BUG的难点,似乎找不到理由。后根据多次测试梳理逻辑,终于找到一丝蛛丝马迹。

打开热点必须关闭WIFI,所以BUG是在关闭热点后,马上再次打开情况下发生的。这时候根据自己添加的代码LOG,发现再次打开时Wifi的状态是关闭。这是该BUG出现的关键。按逻辑,若WIFI的原始状态是打开,点击关闭热点会重新打开Wifi,此时获取Wifi的状态应该是打开中,但我猜想可能涉及到多线程操作,在快速点击时这里获取到的Wifi状态是关闭。

由于获取到错误的Wifi状态,所以Wifi明明是打开的,却没有去关闭,造成 设置按钮不可点击-》打开热点操作后,获取不到热点打开成功的广播,造成按钮无法还原,所以再也不能点了,只能退出页面重进。

说了这么多?那该怎么解决呢?

解BUG最好是从根本上解决,但这根本涉及的太深了,搞不定 – – ~

没办法,只能贴块狗皮膏药了,不管黑猫白猫,能抓老鼠就是好猫~不管啥办法,能解决BUG就是好方法。

回头看BUG,点击关闭热点会重新打开Wifi,但是此时Wifi状态是关闭,所以造成后面无法点击,但是Wifi还是会重新打开的!所以我们可以监听Wifi打开的广播,在收到广播后无脑的将按钮设置为可以点击!这样就完美解决了Google的BUG了!嘿嘿,希望能帮到有需要的童鞋。