1.CTS 测试项命令
测试前:
- 设置->显示->Sleep 为 永不
- 锁屏为 none
- 开发者选项-Stay awake 为开启
- USB 调试模式
- run cts -m CtsIncidentHostTestCases -t com.android.server.cts.BatteryStatsValidationTest#testRealtime -o -d
2. BatteryStatsValidationTest#testRealtime
/VTS9.0/VTS/cts/hostsidetests/incident/src/com/android/server/cts/BatteryStatsValidationTest.java
/**
423 * Tests whether the on-battery realtime and total realtime values
424 * are properly updated in battery stats.
425 */
426 public void testRealtime() throws Exception {
427 batteryOnScreenOff();
*********************
// 设置为未充电
getDevice().executeShellCommand("dumpsys battery unplug");
// 设置status为3
getDevice().executeShellCommand("dumpsys battery set status " + BATTERY_STATUS_DISCHARGING);
// 阻止息屏
getDevice().executeShellCommand("dumpsys batterystats enable pretend-screen-off");
*********************
428 long startingValueRealtime = getLongValue(0, "bt", "", 7);
429 long startingValueBatteryRealtime = getLongValue(0, "bt", "", 5);
430 // After going on battery
431 Thread.sleep(2000);
432 batteryOffScreenOn();
*********************
// 恢复初始值
getDevice().executeShellCommand("dumpsys battery reset");
// 取消阻止息屏
getDevice().executeShellCommand("dumpsys batterystats disable pretend-screen-off");
*********************
433 // After going off battery
434 Thread.sleep(2000);
// 当前系统运行时间,包括休眠时间
436 long currentValueRealtime = getLongValue(0, "bt", "", 7);
///电池放电运行时间,包括休眠时间
// mBatteryRealtimeUs = mStats.getBatteryRealtime(rawRealtimeUs);
437 long currentValueBatteryRealtime = getLongValue(0, "bt", "", 5);
438
标准:大于 4000 ms
439 // Total realtime increase should be 4000ms at least
440 assertTrue(currentValueRealtime >= startingValueRealtime + 4000);
441 // But not too much more
标准:小于6000 ms
442 assertTrue(currentValueRealtime < startingValueRealtime + 6000);
443 // Battery on realtime should be more than 2000 but less than 4000
// 大于 2000 ms
444 assertTrue(currentValueBatteryRealtime >= startingValueBatteryRealtime + 2000);
// 小于 4000 ms
445 assertTrue(currentValueBatteryRealtime < startingValueBatteryRealtime + 4000);
446 }
上述CTS测试方法为:
1. 设置手机放电状态,并记录系统运行时间(startingValueRealtime)和电池放电时间(startingValueBatteryRealtime)
2. 延时 2000 ms;
3. 设置手机为充电状态;
4. 延时 2000 ms;
5. 记录此时的系统运行时间(currentValueRealtime)和电池放电时间(currentValueBatteryRealtime)
标准是:
测试后系统运行时间 currentValueRealtime 的数据应在startingValueRealtime + (4000 ~ 6000) ms 之间
测试后电池放电时间 currentValueBatteryRealtime 的数据应在startingValueBatteryRealtime+(2000 ~ 4000) ms 之间
=====================================
检查 dumpsys batterystats --checkin
525 /**
526 * Returns a particular long value from a line matched by uid, tag and the optionalAfterTag.
527 */
528 private long getLongValue(int uid, String tag, String optionalAfterTag, int index)
529 throws Exception {
530 String dumpsys = getDevice().executeShellCommand("dumpsys batterystats --checkin");
531 String[] lines = dumpsys.split("\n");
532 long value = 0;
533 if (optionalAfterTag == null) {
534 optionalAfterTag = "";
535 }
536 for (int i = lines.length - 1; i >= 0; i--) {
537 String line = lines[i];
538 if (line.contains(uid + ",l," + tag + "," + optionalAfterTag)
539 || (!optionalAfterTag.equals("") &&
540 line.contains(uid + ",l," + tag + ",\"" + optionalAfterTag))) {
541 String[] wlParts = line.split(",");
542 value = Long.parseLong(wlParts[index]);
543 }
544 }
545 return value;
546 }
==================================================
查看字段含义
mtk8321-p-u3a10-wifi-dint/frameworks/base/core/java/android/os/BatteryStats.java
private static final String BATTERY_DATA = "bt";
Tokyo_Lite:/ $ dumpsys batterystats --checkin|grep ",bt,"
9,0,l,bt,0,3116524,39962,5492517,2415955,1572325745422,3116524,39962,4060,4060000,4060000,0
3. CTS失败日志
at com.android.server.cts.BatteryStatsValidationTest.testRealtime(BatteryStatsValidationTest.java:442)
439 // Total realtime increase should be 4000ms at least
440 assertTrue(currentValueRealtime >= startingValueRealtime + 4000);
441 // But not too much more
442 assertTrue(currentValueRealtime < startingValueRealtime + 6000);//本项目测试失败
443 // Battery on realtime should be more than 2000 but less than 4000
444 assertTrue(currentValueBatteryRealtime >= startingValueBatteryRealtime + 2000);
445 assertTrue(currentValueBatteryRealtime < startingValueBatteryRealtime + 4000
说明实际系统运行时长 currentValueRealtime 大于最大值 6000 ms
故接下来我们需要再CTS测试用例中新增下日志打印,看下currentValueRealtime是否为正确
异常项目,CTS 是 Fail
// 执行完2个getLongValue() 耗时(47-41 = 6秒)
10-30 09:10:41 W/BatteryStatsValidationTest: testRealtime_1 getLongValue_start
10-30 09:10:47 W/BatteryStatsValidationTest: testRealtime_2 getLongValue_end,startingValueRealtime 2116, startingValueBatteryRealtime4224
// 执行完2个getLongValue() 耗时(55-51 = 4秒)
10-30 09:10:51 W/BatteryStatsValidationTest: testRealtime_3 getLongValue_start
10-30 09:10:55 W/BatteryStatsValidationTest: testRealtime_4 getLongValue_end,currentValueRealtime 10635, currentValueBatteryRealtime8371
正常项目 是 pass的
// 执行完2个getLongValue(),几乎是实时的
10-30 13:10:32 W/BatteryStatsValidationTest: testRealtime_1 getLongValue_start
10-30 13:10:32 W/BatteryStatsValidationTest: testRealtime_2 getLongValue_end,startingValueRealtime 2203689, startingValueBatteryRealtime336869
// 执行完2个getLongValue(),几乎是实时的
10-30 13:10:37 W/BatteryStatsValidationTest: testRealtime_3 getLongValue_start
10-30 13:10:37 W/BatteryStatsValidationTest: testRealtime_4 getLongValue_end,currentValueRealtime 2208350, currentValueBatteryRealtime339122
上述发现 dumpsys batterystats --checkin 需要花费2秒时间
4. 问题原因和解决
发现执行 dumpsys batterystats --checkin 都会有 “timeout reading telephony stats”
原来异常的项目是平板不带modem的,故获取不到modem信息,导致timeout 2秒,导致CTS测试不过,即修正对应modem相关逻辑即可
打印LOG发现:10-30 17:03:21.374 616 673 W BatteryExternalStatsWorker: timeout reading telephony stats
跟踪代码:
final SynchronousResultReceiver.Result result =
508 receiver.awaitResult(EXTERNAL_STATS_SYNC_TIMEOUT_MILLIS);
509 if (result.bundle != null) {
510 // This is the final destination for the Bundle.
511 result.bundle.setDefusable(true);
512
513 final T data = result.bundle.getParcelable(
514 BatteryStats.RESULT_RECEIVER_CONTROLLER_KEY);
515 if (data != null) {
516 return data;
517 }
518 }
519 Slog.e(TAG, "no controller energy info supplied for " + receiver.getName());
520 } catch (TimeoutException e) {
521 Slog.w(TAG, "timeout reading " + receiver.getName() + " stats");
522 }
SynchronousResultReceiver modemReceiver = new SynchronousResultReceiver("telephony");
816 mTelephony.requestModemActivityInfo(modemReceiver);
817 final ModemActivityInfo modemInfo = awaitControllerInfo(modemReceiver);
本案例看CTS是一个很好白盒测试项目