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 package com.android.loganalysis.item;
17 
18 import org.json.JSONArray;
19 import org.json.JSONException;
20 import org.json.JSONObject;
21 
22 import java.util.Arrays;
23 import java.util.Collection;
24 import java.util.HashSet;
25 import java.util.LinkedList;
26 import java.util.Set;
27 
28 /**
29  * An {@link IItem} used to store information related to network bandwidth, sensor usage,
30  * alarm usage by each processes
31  */
32 public class ProcessUsageItem implements IItem {
33 
34     /** Constant for JSON output */
35     public static final String PROCESS_USAGE = "PROCESS_USAGE";
36 
37     private Collection<ProcessUsageInfoItem> mProcessUsage =
38             new LinkedList<ProcessUsageInfoItem>();
39 
40     public static class SensorInfoItem extends GenericItem {
41         /** Constant for JSON output */
42         public static final String  SENSOR_NAME = "SENSOR_NAME";
43         /** Constant for JSON output */
44         public static final String USAGE_DURATION = "USAGE_DURATION";
45 
46         private static final Set<String> ATTRIBUTES = new HashSet<String>(Arrays.asList(
47             SENSOR_NAME, USAGE_DURATION));
48 
49         /**
50          * The constructor for {@link SensorInfoItem}
51          *
52          * @param name The name of the sensor
53          * @param usageDuration Duration of the usage
54          */
SensorInfoItem(String name, long usageDuration)55         public SensorInfoItem(String name, long usageDuration) {
56             super(ATTRIBUTES);
57 
58             setAttribute(SENSOR_NAME, name);
59             setAttribute(USAGE_DURATION, usageDuration);
60         }
61 
62         /**
63          * Get the sensor name
64          */
getSensorName()65         public String getSensorName() {
66             return (String) getAttribute(SENSOR_NAME);
67         }
68 
69         /**
70          * Get the sensor usage duration in milliseconds
71          */
getUsageDurationMs()72         public long getUsageDurationMs() {
73             return (long) getAttribute(USAGE_DURATION);
74         }
75     }
76 
77     public static class ProcessUsageInfoItem extends GenericItem {
78         /** Constant for JSON output */
79         public static final String  ALARM_WAKEUPS = "ALARM_WAKEUPS";
80         /** Constant for JSON output */
81         public static final String SENSOR_USAGE = "SENSOR_USAGE";
82         /** Constant for JSON output */
83         public static final String  PROCESS_UID = "PROCESS_UID";
84 
85         private static final Set<String> ATTRIBUTES = new HashSet<String>(Arrays.asList(
86                 ALARM_WAKEUPS, SENSOR_USAGE, PROCESS_UID));
87 
88         /**
89          * The constructor for {@link ProcessUsageItem}
90          *
91          * @param uid The name of the process
92          * @param alarmWakeups Number of alarm wakeups
93          * @param sensorUsage Different sensors used by the process
94          */
ProcessUsageInfoItem(String uid, int alarmWakeups, LinkedList<SensorInfoItem> sensorUsage)95         public ProcessUsageInfoItem(String uid, int alarmWakeups,
96                 LinkedList<SensorInfoItem> sensorUsage) {
97             super(ATTRIBUTES);
98 
99             setAttribute(PROCESS_UID, uid);
100             setAttribute(ALARM_WAKEUPS, alarmWakeups);
101             setAttribute(SENSOR_USAGE, sensorUsage);
102         }
103 
104         /**
105          * Get the number of Alarm wakeups
106          */
getAlarmWakeups()107         public int getAlarmWakeups() {
108             return (int) getAttribute(ALARM_WAKEUPS);
109         }
110 
111         /**
112          * Get the Sensor usage of the process
113          */
114         @SuppressWarnings("unchecked")
getSensorUsage()115         public LinkedList<SensorInfoItem> getSensorUsage() {
116             return (LinkedList<SensorInfoItem>) getAttribute(SENSOR_USAGE);
117         }
118 
119         /**
120          * Get the process name
121          */
getProcessUID()122         public String getProcessUID() {
123             return (String) getAttribute(PROCESS_UID);
124         }
125 
126         /**
127          * {@inheritDoc}
128          */
129         @Override
toJson()130         public JSONObject toJson() {
131             JSONObject object = new JSONObject();
132             try {
133                 object.put(PROCESS_UID, getProcessUID());
134                 JSONArray sensorUsage = new JSONArray();
135                 for (SensorInfoItem usage : getSensorUsage()) {
136                     sensorUsage.put(usage.toJson());
137                 }
138                 object.put(SENSOR_USAGE, sensorUsage);
139                 object.put(ALARM_WAKEUPS, getAlarmWakeups());
140 
141             } catch (JSONException e) {
142                 // Ignore
143             }
144             return object;
145         }
146     }
147 
148     /**
149      * Add individual process usage from the battery stats section.
150      *
151      * @param processUID The name of the process
152      * @param alarmWakeups The number of alarm wakeups
153      * @param sensorUsage Sensor usage of the process
154      */
addProcessUsage(String processUID, int alarmWakeups, LinkedList<SensorInfoItem> sensorUsage)155     public void addProcessUsage(String processUID, int alarmWakeups,
156             LinkedList<SensorInfoItem> sensorUsage) {
157         mProcessUsage.add(new ProcessUsageInfoItem(processUID, alarmWakeups, sensorUsage));
158     }
159 
160     /**
161      * {@inheritDoc}
162      */
163     @Override
merge(IItem other)164     public IItem merge(IItem other) throws ConflictingItemException {
165         throw new ConflictingItemException("Wakelock items cannot be merged");
166     }
167 
168     /**
169      * {@inheritDoc}
170      */
171     @Override
isConsistent(IItem other)172     public boolean isConsistent(IItem other) {
173         return false;
174     }
175 
getProcessUsage()176     public Collection<ProcessUsageInfoItem> getProcessUsage() {
177         return mProcessUsage;
178     }
179 
180     /**
181      * {@inheritDoc}
182      */
183     @Override
toJson()184     public JSONObject toJson() {
185         JSONObject object = new JSONObject();
186         if (mProcessUsage != null) {
187             try {
188                 JSONArray processUsage = new JSONArray();
189                 for (ProcessUsageInfoItem usage : mProcessUsage) {
190                     processUsage.put(usage.toJson());
191                 }
192                 object.put(PROCESS_USAGE, processUsage);
193             } catch (JSONException e) {
194                 // Ignore
195             }
196         }
197         return object;
198     }
199 }
200