summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorAvinankumar Vellore Suriyakumar <avellore@google.com>2016-01-13 18:52:59 -0800
committerAvinankumar Vellore Suriyakumar <avellore@google.com>2016-01-19 17:19:13 -0800
commitb9b98773204a467f7a6100ff62a33fbb00c9eaf3 (patch)
treed1cc6f54fc6c860cc80680a901ed4cf58a90f6d9 /src
parenta81b9db05d513c1284aed2a2802a193f2ec88b60 (diff)
downloadloganalysis-b9b98773204a467f7a6100ff62a33fbb00c9eaf3.tar.gz
Add more information to analysis
Added more information to analysis. Also added rule for Interrupts Change-Id: I090ec531d170693a3a96047a02c3b057cfb80bb4
Diffstat (limited to 'src')
-rw-r--r--src/com/android/loganalysis/item/InterruptItem.java7
-rw-r--r--src/com/android/loganalysis/parser/InterruptParser.java2
-rw-r--r--src/com/android/loganalysis/rule/InterruptRule.java87
-rw-r--r--src/com/android/loganalysis/rule/LocationUsageRule.java56
-rw-r--r--src/com/android/loganalysis/rule/ProcessUsageRule.java80
-rw-r--r--src/com/android/loganalysis/rule/RuleEngine.java1
-rw-r--r--src/com/android/loganalysis/rule/WakelockRule.java28
-rw-r--r--src/com/android/loganalysis/rule/WifiStatsRule.java33
8 files changed, 234 insertions, 60 deletions
diff --git a/src/com/android/loganalysis/item/InterruptItem.java b/src/com/android/loganalysis/item/InterruptItem.java
index 1169004..4ff7662 100644
--- a/src/com/android/loganalysis/item/InterruptItem.java
+++ b/src/com/android/loganalysis/item/InterruptItem.java
@@ -125,6 +125,13 @@ public class InterruptItem implements IItem {
}
/**
+ * Get a list of {@link InterruptInfoItem} objects
+ */
+ public List<InterruptInfoItem> getInterrupts() {
+ return (List<InterruptInfoItem>) mInterrupts;
+ }
+
+ /**
* {@inheritDoc}
*/
@Override
diff --git a/src/com/android/loganalysis/parser/InterruptParser.java b/src/com/android/loganalysis/parser/InterruptParser.java
index 26417c4..27ccc4c 100644
--- a/src/com/android/loganalysis/parser/InterruptParser.java
+++ b/src/com/android/loganalysis/parser/InterruptParser.java
@@ -70,7 +70,7 @@ public class InterruptParser implements IParser {
}
private InterruptCategory getInterruptCategory(String interruptName) {
- if (interruptName.contains("bcmsdh_sdmmc")) {
+ if (interruptName.contains("bcmsdh_sdmmc") || interruptName.contains("msm_pcie_wake")) {
return InterruptCategory.WIFI_INTERRUPT;
} else if (interruptName.contains("smd-modem") ||
interruptName.contains("smsm-modem")) {
diff --git a/src/com/android/loganalysis/rule/InterruptRule.java b/src/com/android/loganalysis/rule/InterruptRule.java
new file mode 100644
index 0000000..ab8e678
--- /dev/null
+++ b/src/com/android/loganalysis/rule/InterruptRule.java
@@ -0,0 +1,87 @@
+/*
+ * Copyright (C) 2016 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.rule;
+
+import com.android.loganalysis.item.BugreportItem;
+import com.android.loganalysis.item.InterruptItem;
+import com.android.loganalysis.item.InterruptItem.InterruptInfoItem;
+import com.android.loganalysis.item.InterruptItem.InterruptCategory;
+
+import java.util.concurrent.TimeUnit;
+import java.util.ArrayList;
+import java.util.List;
+
+import org.json.JSONException;
+import org.json.JSONObject;
+
+/**
+ * Rules definition for Interrupt rule
+ */
+public class InterruptRule extends AbstractPowerRule {
+
+ private static final String INTERRUPT_ANALYSIS = "INTERRUPT_ANALYSIS";
+ private static final long INTERRUPT_THRESHOLD_MS = 120000;
+
+ private List<InterruptInfoItem> mOffendingInterruptsList;
+
+ public InterruptRule (BugreportItem bugreportItem) {
+ super(bugreportItem);
+ }
+
+ @Override
+ public void applyRule() {
+ mOffendingInterruptsList = new ArrayList<InterruptInfoItem>();
+ InterruptItem interruptItem = getDetailedAnalysisItem().getInterruptItem();
+ if (interruptItem == null || getTimeOnBattery() < 0) {
+ return;
+ }
+ for (InterruptInfoItem interrupts : interruptItem.getInterrupts()) {
+ final long interruptsPerMs = getTimeOnBattery()/interrupts.getInterruptCount();
+ if (interruptsPerMs < INTERRUPT_THRESHOLD_MS) {
+ mOffendingInterruptsList.add(interrupts);
+ }
+ }
+ }
+
+ @Override
+ public JSONObject getAnalysis() {
+ JSONObject interruptAnalysis = new JSONObject();
+ StringBuilder analysis = new StringBuilder();
+ if (mOffendingInterruptsList == null || mOffendingInterruptsList.size() <= 0) {
+ analysis.append(String.format(
+ "No interrupts woke up device more frequent than %d secs.",
+ TimeUnit.MILLISECONDS.toSeconds(INTERRUPT_THRESHOLD_MS)));
+ } else {
+ for (InterruptInfoItem interrupts : mOffendingInterruptsList) {
+ if (interrupts.getCategory() != InterruptCategory.UNKNOWN_INTERRUPT) {
+ analysis.append(String.format("Frequent interrupts from %s (%s). ",
+ interrupts.getCategory(),
+ interrupts.getName()));
+ } else {
+ analysis.append(String.format("Frequent interrupts from %s. ",
+ interrupts.getName()));
+ }
+ }
+ }
+ try {
+ interruptAnalysis.put(INTERRUPT_ANALYSIS, analysis.toString().trim());
+ } catch (JSONException e) {
+ // do nothing
+ }
+ return interruptAnalysis;
+ }
+}
diff --git a/src/com/android/loganalysis/rule/LocationUsageRule.java b/src/com/android/loganalysis/rule/LocationUsageRule.java
index 71defa2..ad208aa 100644
--- a/src/com/android/loganalysis/rule/LocationUsageRule.java
+++ b/src/com/android/loganalysis/rule/LocationUsageRule.java
@@ -21,13 +21,15 @@ import com.android.loganalysis.item.LocationDumpsItem;
import com.android.loganalysis.item.LocationDumpsItem.LocationInfoItem;
import java.util.concurrent.TimeUnit;
+import java.util.ArrayList;
+import java.util.List;
import org.json.JSONException;
import org.json.JSONObject;
/**
- * Rules definition for Process usage
+ * Rules definition for Location usage
*/
public class LocationUsageRule extends AbstractPowerRule {
@@ -36,48 +38,58 @@ public class LocationUsageRule extends AbstractPowerRule {
// GSA requests for location every 285 seconds, anything more frequent is an issue
private static final int LOCATION_INTERVAL_THRESHOLD = 285;
- private StringBuffer mAnalysisBuffer;
-
- private BugreportItem mBugreportItem = null;
+ private List<LocationInfoItem> mOffendingLocationRequestList;
+ private BugreportItem mBugreportItem;
public LocationUsageRule (BugreportItem bugreportItem) {
super(bugreportItem);
mBugreportItem = bugreportItem;
}
-
@Override
public void applyRule() {
- mAnalysisBuffer = new StringBuffer();
+ mOffendingLocationRequestList = new ArrayList<LocationInfoItem>();
+ if (mBugreportItem.getActivityService() == null || getTimeOnBattery() <= 0) {
+ return;
+ }
LocationDumpsItem locationDumpsItem = mBugreportItem.getActivityService()
.getLocationDumps();
+ if (locationDumpsItem == null) {
+ return;
+ }
final long locationRequestThresholdMs = (long) (getTimeOnBattery() *
LOCATION_REQUEST_DURATION_THRESHOLD);
- if (locationDumpsItem != null) {
- for (LocationInfoItem locationClient : locationDumpsItem.getLocationClients()) {
- final String packageName = locationClient.getPackage();
- final String priority = locationClient.getPriority();
- final int effectiveIntervalSec = locationClient.getEffectiveInterval();
- if (effectiveIntervalSec < LOCATION_INTERVAL_THRESHOLD &&
- !priority.equals("PRIORITY_NO_POWER") &&
- (TimeUnit.MINUTES.toMillis(locationClient.getDuration()) >
- locationRequestThresholdMs)) {
- mAnalysisBuffer.append(String.format("Package %s is requesting for location "
- + "updates every %d secs with priority %s", packageName,
- effectiveIntervalSec, priority));
- }
+
+ for (LocationInfoItem locationClient : locationDumpsItem.getLocationClients()) {
+ final String priority = locationClient.getPriority();
+ final int effectiveIntervalSec = locationClient.getEffectiveInterval();
+ if (effectiveIntervalSec < LOCATION_INTERVAL_THRESHOLD &&
+ !priority.equals("PRIORITY_NO_POWER") &&
+ (TimeUnit.MINUTES.toMillis(locationClient.getDuration()) >
+ locationRequestThresholdMs)) {
+ mOffendingLocationRequestList.add(locationClient);
}
}
}
@Override
public JSONObject getAnalysis() {
- JSONObject usageAnalysis = new JSONObject();
+ JSONObject locationAnalysis = new JSONObject();
+ StringBuilder analysis = new StringBuilder();
+ if (mOffendingLocationRequestList == null || mOffendingLocationRequestList.size() <= 0) {
+ analysis.append("No apps requested for frequent location updates. ");
+ } else {
+ for (LocationInfoItem locationClient : mOffendingLocationRequestList) {
+ analysis.append(String.format("Package %s is requesting for location "
+ +"updates every %d secs with priority %s.", locationClient.getPackage(),
+ locationClient.getEffectiveInterval(), locationClient.getPriority()));
+ }
+ }
try {
- usageAnalysis.put(LOCATION_USAGE_ANALYSIS, mAnalysisBuffer.toString());
+ locationAnalysis.put(LOCATION_USAGE_ANALYSIS, analysis.toString().trim());
} catch (JSONException e) {
// do nothing
}
- return usageAnalysis;
+ return locationAnalysis;
}
}
diff --git a/src/com/android/loganalysis/rule/ProcessUsageRule.java b/src/com/android/loganalysis/rule/ProcessUsageRule.java
index 4e15aee..876bdd1 100644
--- a/src/com/android/loganalysis/rule/ProcessUsageRule.java
+++ b/src/com/android/loganalysis/rule/ProcessUsageRule.java
@@ -17,9 +17,14 @@
package com.android.loganalysis.rule;
import com.android.loganalysis.item.BugreportItem;
-import com.android.loganalysis.item.DumpsysProcStatsItem;
import com.android.loganalysis.item.ProcessUsageItem;
import com.android.loganalysis.item.ProcessUsageItem.ProcessUsageInfoItem;
+import com.android.loganalysis.item.ProcessUsageItem.SensorInfoItem;
+
+import com.android.loganalysis.util.NumberFormattingUtil;
+
+import java.util.ArrayList;
+import java.util.List;
import org.json.JSONException;
import org.json.JSONObject;
@@ -30,10 +35,13 @@ import org.json.JSONObject;
*/
public class ProcessUsageRule extends AbstractPowerRule {
- private static final String PROCESS_USAGE_ANALYSIS = "PROCESS_USAGE_ANALYSIS";
+ private static final String ALARM_USAGE_ANALYSIS = "ALARM_USAGE_ANALYSIS";
+ private static final String SENSOR_USAGE_ANALYSIS = "SENSOR_USAGE_ANALYSIS";
private static final long ALARM_THRESHOLD = 60000;
+ private static final float SENSOR_ACTIVE_TIME_THRESHOLD_PERCENTAGE = 0.1f; // 10%
- private StringBuffer mAnalysisBuffer;
+ private List<ProcessUsageInfoItem> mOffendingAlarmList;
+ private List<ProcessUsageInfoItem> mOffendingSensorList;
public ProcessUsageRule (BugreportItem bugreportItem) {
super(bugreportItem);
@@ -42,34 +50,70 @@ public class ProcessUsageRule extends AbstractPowerRule {
@Override
public void applyRule() {
- mAnalysisBuffer = new StringBuffer();
+ mOffendingAlarmList = new ArrayList<ProcessUsageInfoItem>();
+ mOffendingSensorList = new ArrayList<ProcessUsageInfoItem>();
+
ProcessUsageItem processUsageItem = getDetailedAnalysisItem().getProcessUsageItem();
- DumpsysProcStatsItem procStatsItem = getProcStatsItem();
- if (processUsageItem != null && procStatsItem!= null) {
+ if (processUsageItem != null && getTimeOnBattery() > 0) {
for (ProcessUsageInfoItem usage : processUsageItem.getProcessUsage()) {
if (usage.getAlarmWakeups() > 0) {
- final long alarmsPerMs = getTimeOnBattery()/usage.getAlarmWakeups();
- if (alarmsPerMs < ALARM_THRESHOLD) {
- final String processName = procStatsItem.get(usage.getProcessUID());
- if (processName != null) {
- mAnalysisBuffer.append(processName);
- } else {
- mAnalysisBuffer.append(usage.getProcessUID());
- }
- mAnalysisBuffer.append(" has requested frequent repeating alarms");
- }
+ addAlarmAnalysis(usage);
+ }
+ if (usage.getSensorUsage() != null && usage.getSensorUsage().size() > 0) {
+ addSensorAnalysis(usage);
}
}
}
}
+ private void addAlarmAnalysis(ProcessUsageInfoItem usage) {
+ final long alarmsPerMs = getTimeOnBattery()/usage.getAlarmWakeups();
+ if (alarmsPerMs < ALARM_THRESHOLD) {
+ mOffendingAlarmList.add(usage);
+ }
+ }
+
+ private void addSensorAnalysis(ProcessUsageInfoItem usage) {
+ final long sensorUsageThresholdMs = (long) (getTimeOnBattery()
+ * SENSOR_ACTIVE_TIME_THRESHOLD_PERCENTAGE);
+ for (SensorInfoItem sensorInfo : usage.getSensorUsage()) {
+ if (sensorInfo.getUsageDurationMs() > sensorUsageThresholdMs) {
+ mOffendingSensorList.add(usage);
+ }
+ }
+ }
+
@Override
public JSONObject getAnalysis() {
JSONObject usageAnalysis = new JSONObject();
+ StringBuilder alarmAnalysis = new StringBuilder();
+ if (mOffendingAlarmList == null || mOffendingAlarmList.size() <= 0) {
+ alarmAnalysis.append("No apps requested for alarms more frequent than 60 secs.");
+ } else {
+ for (ProcessUsageInfoItem alarmInfo : mOffendingAlarmList) {
+ alarmAnalysis.append(String.format(
+ "UID %s has requested frequent repeating alarms. ",
+ alarmInfo.getProcessUID()));
+ }
+ }
+ StringBuilder sensorAnalysis = new StringBuilder();
+ if (mOffendingSensorList == null || mOffendingSensorList.size() <= 0) {
+ sensorAnalysis.append("No apps used sensors more than 10% time on battery.");
+ } else {
+ for (ProcessUsageInfoItem sensorInfo : mOffendingSensorList) {
+ for (SensorInfoItem sensors : sensorInfo.getSensorUsage()) {
+ sensorAnalysis.append(String.format("sensor %s was used for %s by UID %s. ",
+ sensors.getSensorName(),
+ NumberFormattingUtil.getDuration(sensors.getUsageDurationMs()),
+ sensorInfo.getProcessUID()));
+ }
+ }
+ }
try {
- usageAnalysis.put(PROCESS_USAGE_ANALYSIS, mAnalysisBuffer.toString());
+ usageAnalysis.put(ALARM_USAGE_ANALYSIS, alarmAnalysis.toString().trim());
+ usageAnalysis.put(SENSOR_USAGE_ANALYSIS, sensorAnalysis.toString().trim());
} catch (JSONException e) {
- // do nothing
+ // do nothing
}
return usageAnalysis;
}
diff --git a/src/com/android/loganalysis/rule/RuleEngine.java b/src/com/android/loganalysis/rule/RuleEngine.java
index 61c2081..728eeb8 100644
--- a/src/com/android/loganalysis/rule/RuleEngine.java
+++ b/src/com/android/loganalysis/rule/RuleEngine.java
@@ -68,5 +68,6 @@ public class RuleEngine {
mRulesList.add(new ProcessUsageRule(mBugreportItem));
mRulesList.add(new LocationUsageRule(mBugreportItem));
mRulesList.add(new WifiStatsRule(mBugreportItem));
+ mRulesList.add(new InterruptRule(mBugreportItem));
}
}
diff --git a/src/com/android/loganalysis/rule/WakelockRule.java b/src/com/android/loganalysis/rule/WakelockRule.java
index b2db2cd..3be02ee 100644
--- a/src/com/android/loganalysis/rule/WakelockRule.java
+++ b/src/com/android/loganalysis/rule/WakelockRule.java
@@ -21,6 +21,9 @@ import com.android.loganalysis.item.WakelockItem;
import com.android.loganalysis.item.WakelockItem.WakelockInfoItem;
import com.android.loganalysis.util.NumberFormattingUtil;
+import java.util.ArrayList;
+import java.util.List;
+
import org.json.JSONException;
import org.json.JSONObject;
@@ -32,25 +35,23 @@ public class WakelockRule extends AbstractPowerRule {
private static final String WAKELOCK_ANALYSIS = "WAKELOCK_ANALYSIS";
private static final float WAKELOCK_HELD_TIME_THRESHOLD_PERCENTAGE = 0.1f; // 10%
- private String mAnalysis = null;
+ private List<WakelockInfoItem> mOffendingWakelockList;
public WakelockRule (BugreportItem bugreportItem) {
super(bugreportItem);
}
- @SuppressWarnings("cast")
@Override
public void applyRule() {
+ mOffendingWakelockList = new ArrayList<WakelockInfoItem>();
WakelockItem wakelockItem = getDetailedAnalysisItem().getWakelockItem();
- if (wakelockItem != null) {
+ if (wakelockItem != null && getTimeOnBattery() > 0) {
long wakelockThreshold = (long)(getTimeOnBattery()
* WAKELOCK_HELD_TIME_THRESHOLD_PERCENTAGE);
for (WakelockInfoItem wakelocks : wakelockItem.getWakeLocks()) {
if (wakelocks.getHeldTime() > wakelockThreshold) {
- mAnalysis = String.format("%s %s is held for %s", wakelocks.getName(),
- wakelocks.getCategory(),
- NumberFormattingUtil.getDuration(wakelocks.getHeldTime()));
+ mOffendingWakelockList.add(wakelocks);
}
}
}
@@ -59,10 +60,19 @@ public class WakelockRule extends AbstractPowerRule {
@Override
public JSONObject getAnalysis() {
JSONObject wakelockAnalysis = new JSONObject();
- try {
- if (mAnalysis != null) {
- wakelockAnalysis.put(WAKELOCK_ANALYSIS, mAnalysis);
+
+ StringBuilder analysis = new StringBuilder();
+ if (mOffendingWakelockList == null || mOffendingWakelockList.size() <= 0) {
+ analysis.append("No wakelocks were held for more than 10% of time on battery.");
+ } else {
+ for (WakelockInfoItem wakelocks : mOffendingWakelockList) {
+ analysis.append(String.format("%s %s is held for %s. ", wakelocks.getName(),
+ wakelocks.getCategory(),
+ NumberFormattingUtil.getDuration(wakelocks.getHeldTime())));
}
+ }
+ try {
+ wakelockAnalysis.put(WAKELOCK_ANALYSIS, analysis.toString().trim());
} catch (JSONException e) {
// do nothing
}
diff --git a/src/com/android/loganalysis/rule/WifiStatsRule.java b/src/com/android/loganalysis/rule/WifiStatsRule.java
index 4a20520..f9bca39 100644
--- a/src/com/android/loganalysis/rule/WifiStatsRule.java
+++ b/src/com/android/loganalysis/rule/WifiStatsRule.java
@@ -25,7 +25,7 @@ import org.json.JSONException;
import org.json.JSONObject;
/**
- * Rules definition for Process usage
+ * Rules definition for Wifi stats
*/
public class WifiStatsRule extends AbstractPowerRule {
@@ -34,7 +34,9 @@ public class WifiStatsRule extends AbstractPowerRule {
// Wifi scans are scheduled by GSA every 285 seconds, anything more frequent is an issue
private static final long WIFI_SCAN_INTERVAL_THRESHOLD_MS = 285000;
- private StringBuffer mAnalysisBuffer;
+ private long mFrequentWifiScansIntervalSecs = 0;
+ private int mNumFrequentWifiDisconnects = 0;
+
private BugreportItem mBugreportItem = null;
public WifiStatsRule (BugreportItem bugreportItem) {
@@ -44,7 +46,6 @@ public class WifiStatsRule extends AbstractPowerRule {
@Override
public void applyRule() {
- mAnalysisBuffer = new StringBuffer();
if (mBugreportItem.getDumpsys() == null || getTimeOnBattery() <= 0) {
return;
}
@@ -57,21 +58,33 @@ public class WifiStatsRule extends AbstractPowerRule {
dumpsysWifiStatsItem.getNumWifiScans();
if (observedWifiScanIntervalMs < WIFI_SCAN_INTERVAL_THRESHOLD_MS) {
- mAnalysisBuffer.append(String.format("Wifi scans happened every %d seconds.",
- TimeUnit.MILLISECONDS.toSeconds(observedWifiScanIntervalMs)));
- }
- if (dumpsysWifiStatsItem.getNumWifiDisconnects() >= WIFI_DISCONNECT_THRESHOLD) {
- mAnalysisBuffer.append(String.format("Wifi got disconnected %d times",
- dumpsysWifiStatsItem.getNumWifiDisconnects()));
+ mFrequentWifiScansIntervalSecs = TimeUnit.MILLISECONDS.toSeconds(
+ observedWifiScanIntervalMs);
}
}
+ if (dumpsysWifiStatsItem.getNumWifiDisconnects() >= WIFI_DISCONNECT_THRESHOLD) {
+ mNumFrequentWifiDisconnects = dumpsysWifiStatsItem.getNumWifiDisconnects();
+ }
}
@Override
public JSONObject getAnalysis() {
JSONObject wifiStatsAnalysis = new JSONObject();
+ StringBuilder analysis = new StringBuilder();
+ if (mFrequentWifiScansIntervalSecs == 0) {
+ analysis.append("No apps requested for frequent wifi scans. ");
+ } else {
+ analysis.append(String.format("Wifi scans happened every %d seconds. ",
+ mFrequentWifiScansIntervalSecs));
+ }
+ if (mNumFrequentWifiDisconnects == 0) {
+ analysis.append("No frequent wifi disconnects were observed. ");
+ } else {
+ analysis.append(String.format("Wifi got disconnected %d times. ",
+ mNumFrequentWifiDisconnects));
+ }
try {
- wifiStatsAnalysis.put(WIFI_STATS, mAnalysisBuffer.toString());
+ wifiStatsAnalysis.put(WIFI_STATS, analysis.toString().trim());
} catch (JSONException e) {
// do nothing
}