1 /* 2 * Copyright (C) 2016 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package com.android.loganalysis.parser; 18 19 import com.android.loganalysis.item.BatteryDischargeStatsInfoItem; 20 import com.android.loganalysis.util.NumberFormattingUtil; 21 22 import java.util.List; 23 import java.util.regex.Matcher; 24 import java.util.regex.Pattern; 25 26 /** 27 * A {@link IParser} to parse the battery discharge section. 28 */ 29 public class BatteryDischargeStatsInfoParser extends AbstractSectionParser { 30 31 /** Matches; #47: +5m5s105ms to 47 (screen-on, power-save-off, device-idle-off) */ 32 private static final Pattern DISCHARGE_STEP_PATTERN = 33 Pattern.compile("^.*: \\+((\\d+)h)?((\\d+)m)?((\\d+)s)?(\\d+)ms.* to (\\d+).*"); 34 35 /** 36 * {@inheritDoc} 37 * 38 * @return The {@link BatteryDischargeStatsInfoItem}. 39 */ 40 @Override parse(List<String> lines)41 public BatteryDischargeStatsInfoItem parse(List<String> lines) { 42 long totalDuration = 0; 43 long projectionDuration = 0; 44 Integer minPercent = null; 45 Integer maxPercent = null; 46 Integer minProjectionPercent = null; 47 Integer maxProjectionPercent = null; 48 49 for (String line : lines) { 50 Matcher m = DISCHARGE_STEP_PATTERN.matcher(line); 51 52 if (m.matches()) { 53 int percent = Integer.parseInt(m.group(8)); 54 55 if (minPercent == null || percent < minPercent) { 56 minPercent = percent; 57 } 58 59 if (maxPercent == null || maxPercent < percent) { 60 maxPercent = percent; 61 } 62 63 long duration = NumberFormattingUtil.getMs( 64 NumberFormattingUtil.parseIntOrZero(m.group(2)), 65 NumberFormattingUtil.parseIntOrZero(m.group(4)), 66 NumberFormattingUtil.parseIntOrZero(m.group(6)), 67 NumberFormattingUtil.parseIntOrZero(m.group(7))); 68 69 totalDuration += duration; 70 71 // For computing the projected battery life we drop the first 5% of the battery 72 // charge because these discharge 'slower' and are not reliable for the projection. 73 if (percent > 94) { 74 continue; 75 } 76 77 if (minProjectionPercent == null || percent < minProjectionPercent) { 78 minProjectionPercent = percent; 79 } 80 81 if (maxProjectionPercent == null || maxProjectionPercent < percent) { 82 maxProjectionPercent = percent; 83 } 84 85 projectionDuration += duration; 86 } 87 } 88 89 if (minPercent == null) { 90 return null; 91 } 92 93 int dischargePercent = maxPercent - minPercent + 1; 94 95 BatteryDischargeStatsInfoItem item = new BatteryDischargeStatsInfoItem(); 96 item.setDischargeDuration(totalDuration); 97 item.setDischargePercentage(dischargePercent); 98 item.setMaxPercentage(maxPercent); 99 item.setMinPercentage(minPercent); 100 101 if (minProjectionPercent == null) { 102 return item; 103 } 104 105 int projectionDischargePercent = maxProjectionPercent - minProjectionPercent + 1; 106 item.setProjectedBatteryLife((projectionDuration * 100) / projectionDischargePercent); 107 return item; 108 } 109 } 110