Home | History | Annotate | Download | only in rule
      1 /*
      2  * Copyright (C) 2015 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.rule;
     18 
     19 import com.android.loganalysis.item.BugreportItem;
     20 import com.android.loganalysis.item.ProcessUsageItem;
     21 import com.android.loganalysis.item.ProcessUsageItem.ProcessUsageInfoItem;
     22 import com.android.loganalysis.item.ProcessUsageItem.SensorInfoItem;
     23 
     24 import com.android.loganalysis.util.NumberFormattingUtil;
     25 
     26 import java.util.ArrayList;
     27 import java.util.List;
     28 
     29 import org.json.JSONException;
     30 import org.json.JSONObject;
     31 
     32 
     33 /**
     34  * Rules definition for Process usage
     35  */
     36 public class ProcessUsageRule extends AbstractPowerRule {
     37 
     38     private static final String ALARM_USAGE_ANALYSIS = "ALARM_USAGE_ANALYSIS";
     39     private static final String SENSOR_USAGE_ANALYSIS = "SENSOR_USAGE_ANALYSIS";
     40     private static final long ALARM_THRESHOLD = 60000;
     41     private static final float SENSOR_ACTIVE_TIME_THRESHOLD_PERCENTAGE = 0.1f; // 10%
     42 
     43     private List<ProcessUsageInfoItem> mOffendingAlarmList;
     44     private List<ProcessUsageInfoItem> mOffendingSensorList;
     45 
     46     public ProcessUsageRule (BugreportItem bugreportItem) {
     47         super(bugreportItem);
     48     }
     49 
     50 
     51     @Override
     52     public void applyRule() {
     53         mOffendingAlarmList = new ArrayList<ProcessUsageInfoItem>();
     54         mOffendingSensorList = new ArrayList<ProcessUsageInfoItem>();
     55 
     56         ProcessUsageItem processUsageItem = getDetailedAnalysisItem().getProcessUsageItem();
     57         if (processUsageItem != null && getTimeOnBattery() > 0) {
     58             for (ProcessUsageInfoItem usage : processUsageItem.getProcessUsage()) {
     59                 if (usage.getAlarmWakeups() > 0) {
     60                     addAlarmAnalysis(usage);
     61                 }
     62                 if (usage.getSensorUsage() != null && usage.getSensorUsage().size() > 0) {
     63                     addSensorAnalysis(usage);
     64                 }
     65             }
     66         }
     67     }
     68 
     69     private void addAlarmAnalysis(ProcessUsageInfoItem usage) {
     70         final long alarmsPerMs = getTimeOnBattery()/usage.getAlarmWakeups();
     71         if (alarmsPerMs < ALARM_THRESHOLD) {
     72             mOffendingAlarmList.add(usage);
     73         }
     74     }
     75 
     76     private void addSensorAnalysis(ProcessUsageInfoItem usage) {
     77         final long sensorUsageThresholdMs = (long) (getTimeOnBattery()
     78                 * SENSOR_ACTIVE_TIME_THRESHOLD_PERCENTAGE);
     79         for (SensorInfoItem sensorInfo : usage.getSensorUsage()) {
     80             if (sensorInfo.getUsageDurationMs() > sensorUsageThresholdMs) {
     81                 mOffendingSensorList.add(usage);
     82             }
     83         }
     84     }
     85 
     86     @Override
     87     public JSONObject getAnalysis() {
     88         JSONObject usageAnalysis = new JSONObject();
     89         StringBuilder alarmAnalysis = new StringBuilder();
     90         if (mOffendingAlarmList == null || mOffendingAlarmList.size() <= 0) {
     91             alarmAnalysis.append("No apps requested for alarms more frequent than 60 secs.");
     92         } else {
     93             for (ProcessUsageInfoItem alarmInfo : mOffendingAlarmList) {
     94                 alarmAnalysis.append(String.format(
     95                         "UID %s has requested frequent repeating alarms. ",
     96                         alarmInfo.getProcessUID()));
     97             }
     98         }
     99         StringBuilder sensorAnalysis = new StringBuilder();
    100         if (mOffendingSensorList == null || mOffendingSensorList.size() <= 0) {
    101             sensorAnalysis.append("No apps used sensors more than 10% time on battery.");
    102         } else {
    103             for (ProcessUsageInfoItem sensorInfo : mOffendingSensorList) {
    104                 for (SensorInfoItem sensors : sensorInfo.getSensorUsage()) {
    105                     sensorAnalysis.append(String.format("sensor %s was used for %s by UID %s. ",
    106                             sensors.getSensorName(),
    107                             NumberFormattingUtil.getDuration(sensors.getUsageDurationMs()),
    108                             sensorInfo.getProcessUID()));
    109                 }
    110             }
    111         }
    112         try {
    113             usageAnalysis.put(ALARM_USAGE_ANALYSIS, alarmAnalysis.toString().trim());
    114             usageAnalysis.put(SENSOR_USAGE_ANALYSIS, sensorAnalysis.toString().trim());
    115         } catch (JSONException e) {
    116             // do nothing
    117         }
    118         return usageAnalysis;
    119     }
    120 }
    121