[蓝牙功耗]通话过程中来蓝牙传输请求,手机拒绝接收,挂掉电话后,手机不能进休眠

描述

[预置条件]

 双卡,打开数据连接,连接假电,待机值正常

[测试步骤]

1.测试机通话中,打开蓝牙,参考机发送图片请求,测试机选择拒绝接收,挂掉电话,LCD灭后观察待机电流;

2.关闭蓝牙,观察待机电流;

[实际结果]

测试机通话过程中来蓝牙传输请求,手机拒绝接收,挂掉电话后,手机不能进休眠平均电流:45.01mA,关掉蓝牙手机仍不能进休眠,平均电流44.95mA,重启手机后正常。(接收传输文件,待机电流正常)

[预期结果]

手机来蓝牙传输请求,接收/拒绝,手机都可以进休眠且待机电流正常。

 

 

问题分析:

看到功耗问题,首先复现问题,测试下来正常的待机电流为10mA左右,而出现问题后,功耗一直维持在40mA左右,且一直降不下来。

然后尝试不进行通话,发现问题还是存在,因此可以排除是通话导致电流升高。

进入设置,将蓝牙关闭后,发现电流还是高,从这里可以大致排除是器件的原因,功耗由软件原因引起的可能性很大。

 

查看log,首先查找wakelock关键字,可以发现在整个log中,有一个蓝牙相关的wakelock一直存在,因此可以确认功耗问题由wakelock引起,因系统无法休眠。

11-28 17:27:45.009442   731  810 D PowerManagerService: wakelock list dump: mLocks.size=1:

11-28 17:27:45.009554   731  810 D PowerManagerService: No.0: PARTIAL_WAKE_LOCK'[Bluetooth.OPP]BtOppObexServer'activated(flags=1, uid=1002, pid=2900)total=194381ms)

11-28 17:27:45.009643   731  810 D PowerManagerService: updateWakeLockSummaryLocked:mWakefulness=Asleep, mWakeLockSummary=0x1

 

查找这个wakelock,所在是BluetoothOppObexServerSession类,其中声明了两个wakelock,以下这个对应的是灭屏时使用的wakelock

mPartialWakeLock =pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, TAG);

 

查找这个wakelock释放的相关代码,仅在以下一处中有调用:

private synchronized void releaseWakeLocks()

 

可注意到这个方法加有同步锁,由于该方法中并没有输出log,因此无法直接判断该方法有无执行。

 

查看log中是否有BluetoothOppObexServerSession输出的其他log,发现有一句log频繁的输出:

11-28 17:27:34.723418  2900 3624 D [Bluetooth.OPP]BtOppObexServer: while loop when serverblocking

 

这段log每隔1秒就会输出,查找到这段log的所在:

while (mServerBlocking) {

   wait(1000);

   Log.d(TAG, "while loop when serverblocking");

   if (mCallback != null && !mTimeoutMsgSent) {

       mCallback.sendMessageDelayed(mCallback

               .obtainMessage(BluetoothOppObexSession.MSG_CONNECT_TIMEOUT),

               BluetoothOppObexSession.SESSION_TIMEOUT);

       mTimeoutMsgSent = true;

       if (V) Log.v(TAG, "MSG_CONNECT_TIMEOUT sent");

    }

}

 

同时可注意到,这段代码也是在同步代码内,因此可以确定,是因为这块代码一直在循环,一直占用同步锁,因此wakelock无法被释放。

 

按照正常流程,在执行等待的过程中,mServerBlocking的值被置为false后,即可脱离循环。

可查看到public void unblock()方法中对该值进行赋值,而使用unblock方法的地方仅有:

BluetoothOppTransfer类中的publicvoid setConfirmed()

而这个方法是用来在接收到用户确认信息时,进行相关操作的

 

查看setConfirmed的使用,仅在BluetoothOppService中和BluetoothOppTransfer自身中有使用,其中以下这段具有比较大的嫌疑,因为在对比的正常log中,是有输出的,但是在异常log中没有输出,其中的confirmed变量,在正常log中为true

if (confirmed) {

   if (V) Log.v(TAG, "Service handle info " + info.mId + "confirmed");

   /* Inbounds transfer get user confirmation, so we start it */

   int i = findBatchWithTimeStamp(info.mTimestamp);

   if (i != -1) {

       BluetoothOppBatch batch = mBatchs.get(i);

       if (mServerTransfer != null && batch.mId ==mServerTransfer.getBatchId()) {

           mServerTransfer.setConfirmed();

       } //TODO need to think about else

    }

}

 

查看confirmed的赋值,相关代码如下:

if (info.mConfirm ==BluetoothShare.USER_CONFIRMATION_PENDING

   && (newConfirm == BluetoothShare.USER_CONFIRMATION_CONFIRMED ||

       newConfirm == BluetoothShare.USER_CONFIRMATION_AUTO_CONFIRMED ||

       newConfirm == BluetoothShare.USER_CONFIRMATION_HANDOVER_CONFIRMED)) {

    confirmed = true;

 }

其中newConfirm的三种状态,分别对应于接受,自动接受,或者是通过nfcwifi等方式接受,而排除掉了3种状态,分别是,等待,拒绝和超时

 

而查看此处的修改记录可发现,有一笔GOOGLE patch在约十天前合入,修改前的代码如下:

if (info.mConfirm ==BluetoothShare.USER_CONFIRMATION_PENDING

       && newConfirm != BluetoothShare.USER_CONFIRMATION_PENDING) {

   confirmed = true;

}

可以看到此patch将拒绝和超时两种状态给排除了,因此当用户拒绝接收文件时,系统无法将confirmed置为true,因此导致while循环一直无法终止。

 

问题的解决:

后续从MTK处了解到,此笔GOOGLE patch仅适用于5.0系统,用于4.4系统会出现上述异常,因此google已经追回此笔patch,而平台也回退了此修改

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值