| /* |
| * Copyright (C) 2015 The Android Open Source Project |
| * |
| * Licensed under the Apache License, Version 2.0 (the "License"); |
| * you may not use this file except in compliance with the License. |
| * You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, software |
| * distributed under the License is distributed on an "AS IS" BASIS, |
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| * See the License for the specific language governing permissions and |
| * limitations under the License. |
| */ |
| |
| package com.android.loganalysis.parser; |
| |
| import com.android.loganalysis.item.BatteryStatsDetailedInfoItem; |
| import com.android.loganalysis.item.BatteryUsageItem; |
| import com.android.loganalysis.item.InterruptItem; |
| import com.android.loganalysis.item.ProcessUsageItem; |
| import com.android.loganalysis.item.WakelockItem; |
| import com.android.loganalysis.util.NumberFormattingUtil; |
| |
| import java.util.List; |
| import java.util.regex.Matcher; |
| import java.util.regex.Pattern; |
| |
| |
| /** |
| * A {@link IParser} to parse the battery stats section of the bugreport |
| */ |
| public class BatteryStatsDetailedInfoParser extends AbstractSectionParser { |
| |
| private static final String BATTERY_USAGE_SECTION_REGEX = "^\\s*Estimated power use \\(mAh\\):$"; |
| private static final String KERNEL_WAKELOCK_SECTION_REGEX = "^\\s*All kernel wake locks:$"; |
| private static final String PARTIAL_WAKELOCK_SECTION_REGEX = "^\\s*All partial wake locks:$"; |
| private static final String INTERRUPT_SECTION_REGEX = "^\\s*All wakeup reasons:$"; |
| private static final String PROCESS_USAGE_SECTION_REGEX = "^\\s*0:$"; |
| |
| /** |
| * Matches: Time on battery: 7h 45m 54s 332ms (98.3%) realtime, 4h 40m 51s 315ms (59.3%) uptime |
| */ |
| private static final Pattern TIME_ON_BATTERY_PATTERN = Pattern.compile( |
| "^\\s*Time on battery: (?:(\\d+)d)?\\s?(?:(\\d+)h)?\\s?(?:(\\d+)m)?\\s?(?:(\\d+)s)?" + |
| "\\s?(?:(\\d+)ms)?.*"); |
| /** |
| * Matches:Time on battery screen off: 1d 4h 6m 16s 46ms (99.1%) realtime, 6h 37m 49s 201ms |
| */ |
| private static final Pattern SCREEN_OFF_TIME_PATTERN = Pattern.compile("^\\s*Time on battery " |
| + "screen off: (?:(\\d+)d)?\\s?(?:(\\d+)h)?\\s?(?:(\\d+)m)?\\s?(?:(\\d+)s)?\\s?" |
| + "(?:(\\d+)ms).*"); |
| |
| private BatteryUsageParser mBatteryUsageParser = new BatteryUsageParser(); |
| private WakelockParser mWakelockParser = new WakelockParser(); |
| private InterruptParser mInterruptParser = new InterruptParser(); |
| private ProcessUsageParser mProcessUsageParser = new ProcessUsageParser(); |
| |
| private IParser mBatteryTimeParser = new IParser() { |
| @Override |
| public BatteryStatsDetailedInfoItem parse(List<String> lines) { |
| BatteryStatsDetailedInfoItem detailedInfo = null; |
| long timeOnBattery = 0, screenOffTime = 0; |
| Matcher m = null; |
| for (String line : lines) { |
| if (detailedInfo == null && !"".equals(line.trim())) { |
| detailedInfo = new BatteryStatsDetailedInfoItem(); |
| } |
| m = TIME_ON_BATTERY_PATTERN.matcher(line); |
| if (m.matches()) { |
| timeOnBattery = NumberFormattingUtil.getMs( |
| NumberFormattingUtil.parseIntOrZero(m.group(1)), |
| NumberFormattingUtil.parseIntOrZero(m.group(2)), |
| NumberFormattingUtil.parseIntOrZero(m.group(3)), |
| NumberFormattingUtil.parseIntOrZero(m.group(4)), |
| NumberFormattingUtil.parseIntOrZero(m.group(5))); |
| detailedInfo.setTimeOnBattery(timeOnBattery); |
| } else { |
| m = SCREEN_OFF_TIME_PATTERN.matcher(line); |
| if (m.matches()) { |
| screenOffTime = NumberFormattingUtil.getMs( |
| NumberFormattingUtil.parseIntOrZero(m.group(1)), |
| NumberFormattingUtil.parseIntOrZero(m.group(2)), |
| NumberFormattingUtil.parseIntOrZero(m.group(3)), |
| NumberFormattingUtil.parseIntOrZero(m.group(4)), |
| NumberFormattingUtil.parseIntOrZero(m.group(5))); |
| detailedInfo.setScreenOnTime(getScreenOnTime(timeOnBattery, screenOffTime)); |
| return detailedInfo; |
| } |
| } |
| } |
| return detailedInfo; |
| } |
| |
| private long getScreenOnTime(long timeOnBattery, long screenOffTime) { |
| if (timeOnBattery > screenOffTime) { |
| return (timeOnBattery - screenOffTime); |
| } |
| return 0; |
| } |
| }; |
| |
| private BatteryStatsDetailedInfoItem mBatteryStatsDetailedInfoItem = null; |
| private boolean mParsedInput = false; |
| |
| /** |
| * {@inheritDoc} |
| * |
| * @return The {@link BatteryStatsDetailedInfoItem} |
| */ |
| @Override |
| public BatteryStatsDetailedInfoItem parse(List<String> lines) { |
| setup(); |
| for (String line : lines) { |
| if (!mParsedInput && !"".equals(line.trim())) { |
| mParsedInput = true; |
| } |
| parseLine(line); |
| } |
| commit(); |
| return mBatteryStatsDetailedInfoItem; |
| } |
| |
| /** |
| * Sets up the parser by adding the section parsers. |
| */ |
| protected void setup() { |
| setParser(mBatteryTimeParser); |
| addSectionParser(mBatteryUsageParser, BATTERY_USAGE_SECTION_REGEX); |
| addSectionParser(mWakelockParser, KERNEL_WAKELOCK_SECTION_REGEX); |
| addSectionParser(mWakelockParser, PARTIAL_WAKELOCK_SECTION_REGEX); |
| addSectionParser(mInterruptParser, INTERRUPT_SECTION_REGEX); |
| addSectionParser(mProcessUsageParser, PROCESS_USAGE_SECTION_REGEX); |
| } |
| |
| /** |
| * Set the {@link BatteryStatsDetailedInfoItem} |
| * |
| */ |
| @Override |
| protected void onSwitchParser() { |
| if (mBatteryStatsDetailedInfoItem == null) { |
| mBatteryStatsDetailedInfoItem = (BatteryStatsDetailedInfoItem) |
| getSection(mBatteryTimeParser); |
| } |
| } |
| |
| /** |
| * {@inheritDoc} |
| */ |
| @Override |
| protected void commit() { |
| // signal EOF |
| super.commit(); |
| if (mParsedInput) { |
| if (mBatteryStatsDetailedInfoItem == null) { |
| mBatteryStatsDetailedInfoItem = new BatteryStatsDetailedInfoItem(); |
| } |
| } |
| |
| if (mBatteryStatsDetailedInfoItem != null) { |
| mBatteryStatsDetailedInfoItem.setBatteryUsageItem( |
| (BatteryUsageItem) getSection(mBatteryUsageParser)); |
| mBatteryStatsDetailedInfoItem.setWakelockItem( |
| (WakelockItem) getSection(mWakelockParser)); |
| mBatteryStatsDetailedInfoItem.setInterruptItem( |
| (InterruptItem) getSection(mInterruptParser)); |
| mBatteryStatsDetailedInfoItem.setProcessUsageItem( |
| (ProcessUsageItem) getSection(mProcessUsageParser)); |
| } |
| } |
| } |