summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authoravellore <avellore@google.com>2015-05-19 12:21:25 -0700
committeravellore <avellore@google.com>2015-05-19 17:22:23 -0700
commitc62fad09df43054df2d755ef7e43d6085656c04b (patch)
treedc972167eb160cf4580c806c52d32b87e0e358fe
parent45eae46848a8ce314029a718ff5e5bded76fe3ce (diff)
downloadloganalysis-c62fad09df43054df2d755ef7e43d6085656c04b.tar.gz
Parse the battery usage statistics
Change-Id: I5000e4352ded2eaa004bc486242c241bcdf4dada
-rw-r--r--src/com/android/loganalysis/item/BatteryStatsDetailedInfoItem.java20
-rw-r--r--src/com/android/loganalysis/item/BatteryUsageItem.java137
-rw-r--r--src/com/android/loganalysis/parser/BatteryStatsDetailedInfoParser.java14
-rw-r--r--src/com/android/loganalysis/parser/BatteryUsageParser.java68
-rw-r--r--tests/src/com/android/loganalysis/item/BatteryUsageItemTest.java53
-rw-r--r--tests/src/com/android/loganalysis/parser/BatteryUsageParserTest.java56
6 files changed, 344 insertions, 4 deletions
diff --git a/src/com/android/loganalysis/item/BatteryStatsDetailedInfoItem.java b/src/com/android/loganalysis/item/BatteryStatsDetailedInfoItem.java
index a1ac0b0..6a06f4e 100644
--- a/src/com/android/loganalysis/item/BatteryStatsDetailedInfoItem.java
+++ b/src/com/android/loganalysis/item/BatteryStatsDetailedInfoItem.java
@@ -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;
@@ -76,6 +79,13 @@ public class BatteryStatsDetailedInfoItem implements IItem {
}
/**
+ * Set the process usage {@link BatteryUsageItem}
+ */
+ public void setBatteryUsageItem(BatteryUsageItem batteryUsageItem) {
+ mBatteryUsageItem = batteryUsageItem;
+ }
+
+ /**
* Get the time on battery
*/
public long getTimeOnBattery() {
@@ -111,6 +121,13 @@ public class BatteryStatsDetailedInfoItem implements IItem {
}
/**
+ * Get the battery usage summary {@link BatteryUsageItem}
+ */
+ public BatteryUsageItem getBatteryUsageItem() {
+ return mBatteryUsageItem;
+ }
+
+ /**
* {@inheritDoc}
*/
@Override
@@ -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());
}
diff --git a/src/com/android/loganalysis/item/BatteryUsageItem.java b/src/com/android/loganalysis/item/BatteryUsageItem.java
new file mode 100644
index 0000000..07bbef3
--- /dev/null
+++ b/src/com/android/loganalysis/item/BatteryUsageItem.java
@@ -0,0 +1,137 @@
+/*
+ * 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;
+ }
+}
diff --git a/src/com/android/loganalysis/parser/BatteryStatsDetailedInfoParser.java b/src/com/android/loganalysis/parser/BatteryStatsDetailedInfoParser.java
index f1bbed0..b800371 100644
--- a/src/com/android/loganalysis/parser/BatteryStatsDetailedInfoParser.java
+++ b/src/com/android/loganalysis/parser/BatteryStatsDetailedInfoParser.java
@@ -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);
@@ -149,17 +153,19 @@ public class BatteryStatsDetailedInfoParser extends AbstractSectionParser {
super.commit();
if (mParsedInput) {
if (mBatteryStatsDetailedInfoItem == null) {
- mBatteryStatsDetailedInfoItem = new BatteryStatsDetailedInfoItem();
+ mBatteryStatsDetailedInfoItem = new BatteryStatsDetailedInfoItem();
}
}
if (mBatteryStatsDetailedInfoItem != null) {
+ mBatteryStatsDetailedInfoItem.setBatteryUsageItem(
+ (BatteryUsageItem) getSection(mBatteryUsageParser));
mBatteryStatsDetailedInfoItem.setWakelockItem(
- (WakelockItem) getSection(mWakelockParser));
+ (WakelockItem) getSection(mWakelockParser));
mBatteryStatsDetailedInfoItem.setInterruptItem(
- (InterruptItem) getSection(mInterruptParser));
+ (InterruptItem) getSection(mInterruptParser));
mBatteryStatsDetailedInfoItem.setProcessUsageItem(
- (ProcessUsageItem) getSection(mProcessUsageParser));
+ (ProcessUsageItem) getSection(mProcessUsageParser));
}
}
}
diff --git a/src/com/android/loganalysis/parser/BatteryUsageParser.java b/src/com/android/loganalysis/parser/BatteryUsageParser.java
new file mode 100644
index 0000000..92cb5d2
--- /dev/null
+++ b/src/com/android/loganalysis/parser/BatteryUsageParser.java
@@ -0,0 +1,68 @@
+/*
+ * 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;
+ }
+}
diff --git a/tests/src/com/android/loganalysis/item/BatteryUsageItemTest.java b/tests/src/com/android/loganalysis/item/BatteryUsageItemTest.java
new file mode 100644
index 0000000..b44a432
--- /dev/null
+++ b/tests/src/com/android/loganalysis/item/BatteryUsageItemTest.java
@@ -0,0 +1,53 @@
+/*
+ * 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));
+ }
+}
diff --git a/tests/src/com/android/loganalysis/parser/BatteryUsageParserTest.java b/tests/src/com/android/loganalysis/parser/BatteryUsageParserTest.java
new file mode 100644
index 0000000..20a9a2e
--- /dev/null
+++ b/tests/src/com/android/loganalysis/parser/BatteryUsageParserTest.java
@@ -0,0 +1,56 @@
+/*
+ * 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());
+ }
+}
+