Skip to content
Snippets Groups Projects
Commit c62fad09 authored by avellore's avatar avellore
Browse files

Parse the battery usage statistics

Change-Id: I5000e4352ded2eaa004bc486242c241bcdf4dada
parent 45eae468
No related branches found
No related tags found
No related merge requests found
......@@ -28,6 +28,8 @@ public class BatteryStatsDetailedInfoItem implements IItem {
/** Constant for JSON output */
public static final String SCREEN_ON_TIME = "SCREEN_ON_TIME";
/** Constant for JSON output */
public static final String BATTERY_USAGE = "BATTERY_USAGE";
/** Constant for JSON output */
public static final String WAKELOCKS = "WAKELOCKS";
/** Constant for JSON output */
public static final String INTERRUPTS = "INTERRUPTS";
......@@ -36,6 +38,7 @@ public class BatteryStatsDetailedInfoItem implements IItem {
private long mTimeOnBattery = 0;
private long mScreenOnTime = 0;
private BatteryUsageItem mBatteryUsageItem = null;
private WakelockItem mWakelockItem = null;
private InterruptItem mInterruptItem = null;
private ProcessUsageItem mprocessUsageItem = null;
......@@ -75,6 +78,13 @@ public class BatteryStatsDetailedInfoItem implements IItem {
mprocessUsageItem = processUsageItem;
}
/**
* Set the process usage {@link BatteryUsageItem}
*/
public void setBatteryUsageItem(BatteryUsageItem batteryUsageItem) {
mBatteryUsageItem = batteryUsageItem;
}
/**
* Get the time on battery
*/
......@@ -110,6 +120,13 @@ public class BatteryStatsDetailedInfoItem implements IItem {
return mprocessUsageItem;
}
/**
* Get the battery usage summary {@link BatteryUsageItem}
*/
public BatteryUsageItem getBatteryUsageItem() {
return mBatteryUsageItem;
}
/**
* {@inheritDoc}
*/
......@@ -139,6 +156,9 @@ public class BatteryStatsDetailedInfoItem implements IItem {
if (mScreenOnTime > 0) {
batteryStatsComponent.put(SCREEN_ON_TIME, getScreenOnTime());
}
if (mBatteryUsageItem != null) {
batteryStatsComponent.put(BATTERY_USAGE, mBatteryUsageItem.toJson());
}
if (mWakelockItem != null) {
batteryStatsComponent.put(WAKELOCKS, mWakelockItem.toJson());
}
......
/*
* 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.item;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import java.util.Arrays;
import java.util.Collection;
import java.util.HashSet;
import java.util.LinkedList;
import java.util.List;
import java.util.Set;
/**
* An {@link IItem} used to store information related to battery usage stats
*/
public class BatteryUsageItem implements IItem {
/** Constant for JSON output */
public static final String BATTERY_USAGE = "BATTERY_USAGE";
/** Constant for JSON output */
public static final String BATTERY_CAPACITY = "BATTERY_CAPACITY";
private Collection<BatteryUsageInfoItem> mBatteryUsage = new LinkedList<BatteryUsageInfoItem>();
private int mBatteryCapacity = 0;
public static class BatteryUsageInfoItem extends GenericItem {
/** Constant for JSON output */
public static final String NAME = "NAME";
/** Constant for JSON output */
public static final String USAGE = "USAGE";
private static final Set<String> ATTRIBUTES = new HashSet<String>(Arrays.asList(
NAME, USAGE));
/**
* The constructor for {@link BatteryUsageItem}
*
* @param name The name of the wake lock
* @param usage Usage in mAh
*/
public BatteryUsageInfoItem(String name, double usage) {
super(ATTRIBUTES);
setAttribute(NAME, name);
setAttribute(USAGE, usage);
}
/**
* Get the name of the wake lock.
*/
public String getName() {
return (String) getAttribute(NAME);
}
/**
* Get the battery usage
*/
public double getUsage() {
return (double) getAttribute(USAGE);
}
}
/**
* Add a battery usage from the battery stats section.
*
* @param name The name of the process
* @param usage The usage in mAh
*/
public void addBatteryUsage(String name, double usage) {
mBatteryUsage.add(new BatteryUsageInfoItem(name, usage));
}
public int getBatteryCapacity() {
return mBatteryCapacity;
}
public List<BatteryUsageInfoItem> getBatteryUsage() {
return (List<BatteryUsageInfoItem>)mBatteryUsage;
}
public void setBatteryCapacity(int capacity) {
mBatteryCapacity = capacity;
}
/**
* {@inheritDoc}
*/
@Override
public IItem merge(IItem other) throws ConflictingItemException {
throw new ConflictingItemException("Wakelock items cannot be merged");
}
/**
* {@inheritDoc}
*/
@Override
public boolean isConsistent(IItem other) {
return false;
}
/**
* {@inheritDoc}
*/
@Override
public JSONObject toJson() {
JSONObject object = new JSONObject();
if (mBatteryUsage != null) {
try {
object.put(BATTERY_CAPACITY, mBatteryCapacity);
JSONArray usageInfo = new JSONArray();
for (BatteryUsageInfoItem usage : mBatteryUsage) {
usageInfo.put(usage.toJson());
}
object.put(BATTERY_USAGE, usageInfo);
} catch (JSONException e) {
// Ignore
}
}
return object;
}
}
......@@ -17,6 +17,7 @@
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;
......@@ -32,6 +33,7 @@ import java.util.regex.Pattern;
*/
public class BatteryStatsDetailedInfoParser extends AbstractSectionParser {
private static final String BATTERY_USAGE_SECTION_REGEX = "^\\s*Estimated power use \\(mAh\\):$";
private static final String WAKELOCK_SECTION_REGEX = "^\\s*All kernel wake locks:$";
private static final String INTERRUPT_SECTION_REGEX = "^\\s*All wakeup reasons:$";
private static final String PROCESS_USAGE_SECTION_REGEX = "^\\s*0:$";
......@@ -49,6 +51,7 @@ public class BatteryStatsDetailedInfoParser extends AbstractSectionParser {
+ "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();
......@@ -123,6 +126,7 @@ public class BatteryStatsDetailedInfoParser extends AbstractSectionParser {
*/
protected void setup() {
setParser(mBatteryTimeParser);
addSectionParser(mBatteryUsageParser, BATTERY_USAGE_SECTION_REGEX);
addSectionParser(mWakelockParser, WAKELOCK_SECTION_REGEX);
addSectionParser(mInterruptParser, INTERRUPT_SECTION_REGEX);
addSectionParser(mProcessUsageParser, PROCESS_USAGE_SECTION_REGEX);
......@@ -154,6 +158,8 @@ public class BatteryStatsDetailedInfoParser extends AbstractSectionParser {
}
if (mBatteryStatsDetailedInfoItem != null) {
mBatteryStatsDetailedInfoItem.setBatteryUsageItem(
(BatteryUsageItem) getSection(mBatteryUsageParser));
mBatteryStatsDetailedInfoItem.setWakelockItem(
(WakelockItem) getSection(mWakelockParser));
mBatteryStatsDetailedInfoItem.setInterruptItem(
......
/*
* 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.BatteryUsageItem;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
/**
* A {@link IParser} to parse battery usage statistics
*/
public class BatteryUsageParser implements IParser {
/**
* Matches: Capacity: 3220, Computed drain: 11.0, actual drain: 0
*/
private static final Pattern Capacity = Pattern.compile(
"^\\s*Capacity: (\\d+), Computed drain: \\d+.*");
private static final Pattern Usage = Pattern.compile("^\\s*(.*): (\\d+(\\.\\d*)?)");
private BatteryUsageItem mItem = new BatteryUsageItem();
/**
* {@inheritDoc}
*
* @return The {@link BatteryUsageItem}.
*/
@Override
public BatteryUsageItem parse(List<String> lines) {
for (String line : lines) {
Matcher m = Capacity.matcher(line);
if(m.matches()) {
mItem.setBatteryCapacity(Integer.parseInt(m.group(1)));
} else {
m = Usage.matcher(line);
if (m.matches()) {
mItem.addBatteryUsage(m.group(1), Double.parseDouble(m.group(2)));
}
}
}
return mItem;
}
/**
* Get the {@link BatteryUsageItem}.
* <p>
* Exposed for unit testing.
* </p>
*/
BatteryUsageItem getItem() {
return mItem;
}
}
/*
* 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.item;
import com.android.loganalysis.item.BatteryUsageItem.BatteryUsageInfoItem;
import junit.framework.TestCase;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
/**
* Unit test for {@link BatteryUsageItem}.
*/
public class BatteryUsageItemTest extends TestCase {
/**
* Test that {@link BatteryUsageItem#toJson()} returns correctly.
*/
public void testToJson() throws JSONException {
BatteryUsageItem item = new BatteryUsageItem();
item.addBatteryUsage("Cell standby", 2925);
item.addBatteryUsage("Uid u0a71", 68.1);
// Convert to JSON string and back again
JSONObject output = new JSONObject(item.toJson().toString());
assertTrue(output.has(BatteryUsageItem.BATTERY_CAPACITY));
assertTrue(output.get(BatteryUsageItem.BATTERY_USAGE) instanceof JSONArray);
JSONArray usage = output.getJSONArray(BatteryUsageItem.BATTERY_USAGE);
assertEquals(2, usage.length());
assertTrue(usage.getJSONObject(0).has(BatteryUsageInfoItem.NAME));
assertTrue(usage.getJSONObject(0).has(BatteryUsageInfoItem.USAGE));
assertTrue(usage.getJSONObject(1).has(BatteryUsageInfoItem.NAME));
assertTrue(usage.getJSONObject(1).has(BatteryUsageInfoItem.USAGE));
}
}
/*
* 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.BatteryUsageItem;
import junit.framework.TestCase;
import java.util.Arrays;
import java.util.List;
/**
* Unit tests for {@link BatteryUsageParser}
*/
public class BatteryUsageParserTest extends TestCase {
private static final double EPSILON = 1e-3;
/**
* Test that normal input is parsed.
*/
public void testBatteryUsageParser() {
List<String> inputBlock = Arrays.asList(
" Capacity: 3220, Computed drain: 11.0, actual drain: 0",
" Screen: 8.93",
" Idle: 1.23",
" Uid 0: 0.281",
" Uid u0a36: 0.200",
" Uid 1000: 0.165",
" Uid 1013: 0.0911",
" Uid u0a16: 0.0441");
BatteryUsageItem usage = new BatteryUsageParser().parse(inputBlock);
assertEquals(3220, usage.getBatteryCapacity());
assertEquals(7, usage.getBatteryUsage().size());
assertEquals("Screen", usage.getBatteryUsage().get(0).getName());
assertEquals(8.93, usage.getBatteryUsage().get(0).getUsage(), EPSILON);
assertEquals("Uid u0a16", usage.getBatteryUsage().get(6).getName());
assertEquals(0.0441, usage.getBatteryUsage().get(6).getUsage());
}
}
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment