我是如何修改Google留下的BUG

2015-04-03 Roger 更多博文 » 博客 » GitHub »

Android Framework

原文链接 http://www.rogerblog.cn/2015/04/02/e6-88-91-e6-98-af-e5-a6-82-e4-bd-95-e4-bf-ae-e6-94-b9google-e7-95-99-e4-b8-8b-e7-9a-84bug/
注:以下为加速网络访问所做的原文缓存,经过重新格式化,可能存在格式方面的问题,或偶有遗漏信息,请以原文为准。


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

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

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; }

<!--more-->

每次点击就是调用这个方法。好的,继续跟进,发现设置热点打开关闭主要是通过 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了!嘿嘿,希望能帮到有需要的童鞋。