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.List;
27 import java.util.Set;
28 
29 /**
30  * An {@link IItem} used to store information related to wake locks and kernel wake locks
31  */
32 public class WakelockItem implements IItem {
33 
34     /** Constant for JSON output */
35     public static final String WAKELOCKS = "WAKELOCKS_INFO";
36 
37     private Collection<WakelockInfoItem> mWakeLocks = new LinkedList<WakelockInfoItem>();
38 
39     /**
40      * Enum for describing the type of wakelock
41      */
42     public enum WakeLockCategory {
43         KERNEL_WAKELOCK,
44         PARTIAL_WAKELOCK,
45     }
46 
47     public static class WakelockInfoItem extends GenericItem {
48         /** Constant for JSON output */
49         public static final String NAME = "NAME";
50         /** Constant for JSON output */
51         public static final String PROCESS_UID = "PROCESS_UID";
52         /** Constant for JSON output */
53         public static final String PROCESS_NAME = "PROCESS_NAME";
54         /** Constant for JSON output */
55         public static final String HELD_TIME = "HELD_TIME";
56         /** Constant for JSON output */
57         public static final String LOCKED_COUNT = "LOCKED_COUNT";
58         /** Constant for JSON output */
59         public static final String CATEGORY = "CATEGORY";
60 
61         private static final Set<String> ATTRIBUTES = new HashSet<String>(Arrays.asList(
62                 NAME, PROCESS_UID, PROCESS_NAME, HELD_TIME, LOCKED_COUNT, CATEGORY));
63 
64         /**
65          * The constructor for {@link WakelockItem}
66          *
67          * @param name The name of the wake lock
68          * @param heldTime The amount of time held in milliseconds
69          * @param lockedCount The number of times the wake lock was locked
70          * @param category The {@link WakeLockCategory} of the wake lock
71          */
WakelockInfoItem(String name, long heldTime, int lockedCount, WakeLockCategory category)72         public WakelockInfoItem(String name, long heldTime, int lockedCount, WakeLockCategory category) {
73             this(name, null, heldTime, lockedCount, category);
74         }
75 
76         /**
77          * The constructor for {@link WakelockItem}
78          *
79          * @param name The name of the wake lock
80          * @param processUID The number of the wake lock
81          * @param heldTime The amount of time held in milliseconds
82          * @param lockedCount The number of times the wake lock was locked
83          * @param category The {@link WakeLockCategory} of the wake lock
84          */
WakelockInfoItem(String name, String processUID, long heldTime, int lockedCount, WakeLockCategory category)85         public WakelockInfoItem(String name, String processUID, long heldTime, int lockedCount,
86                 WakeLockCategory category) {
87             super(ATTRIBUTES);
88 
89             setAttribute(NAME, name);
90             setAttribute(PROCESS_UID, processUID);
91             setAttribute(HELD_TIME, heldTime);
92             setAttribute(LOCKED_COUNT, lockedCount);
93             setAttribute(CATEGORY, category);
94         }
95 
96         /**
97          * Get the name of the wake lock.
98          */
getName()99         public String getName() {
100             return (String) getAttribute(NAME);
101         }
102 
103         /**
104          * Get the process UID holding the wake lock.
105          */
getProcessUID()106         public String getProcessUID() {
107             return (String) getAttribute(PROCESS_UID);
108         }
109 
110         /**
111          * Get the time the wake lock was held in milliseconds.
112          */
getHeldTime()113         public long getHeldTime() {
114             return (Long) getAttribute(HELD_TIME);
115         }
116 
117         /**
118          * Get the number of times the wake lock was locked.
119          */
getLockedCount()120         public int getLockedCount() {
121             return (Integer) getAttribute(LOCKED_COUNT);
122         }
123 
124         /**
125          * Get the {@link WakeLockCategory} of the wake lock.
126          */
getCategory()127         public WakeLockCategory getCategory() {
128             return (WakeLockCategory) getAttribute(CATEGORY);
129         }
130 
131         /**
132          * Set the process name holding the wake lock
133          */
setWakelockProcessName(String processName)134         public void setWakelockProcessName(String processName) {
135             setAttribute(PROCESS_NAME, processName);
136         }
137     }
138 
139     /**
140      * Add a wakelock from the battery stats section.
141      *
142      * @param name The name of the wake lock.
143      * @param processUID The number of the wake lock.
144      * @param heldTime The held time of the wake lock.
145      * @param timesCalled The number of times the wake lock has been called.
146      * @param category The {@link WakeLockCategory} of the wake lock.
147      */
addWakeLock(String name, String processUID, long heldTime, int timesCalled, WakeLockCategory category)148     public void addWakeLock(String name, String processUID, long heldTime, int timesCalled,
149             WakeLockCategory category) {
150         mWakeLocks.add(new WakelockInfoItem(name, processUID, heldTime, timesCalled, category));
151     }
152 
153     /**
154      * Add a wakelock from the battery stats section.
155      *
156      * @param name The name of the wake lock.
157      * @param heldTime The held time of the wake lock.
158      * @param timesCalled The number of times the wake lock has been called.
159      * @param category The {@link WakeLockCategory} of the wake lock.
160      */
addWakeLock(String name, long heldTime, int timesCalled, WakeLockCategory category)161     public void addWakeLock(String name, long heldTime, int timesCalled,
162             WakeLockCategory category) {
163         addWakeLock(name, null, heldTime, timesCalled, category);
164     }
165 
166     /**
167      * Get a list of {@link WakelockInfoItem} objects matching a given {@link WakeLockCategory}.
168      */
getWakeLocks(WakeLockCategory category)169     public List<WakelockInfoItem> getWakeLocks(WakeLockCategory category) {
170         LinkedList<WakelockInfoItem> wakeLocks = new LinkedList<WakelockInfoItem>();
171         if (category == null) {
172             return wakeLocks;
173         }
174 
175         for (WakelockInfoItem wakeLock : mWakeLocks) {
176             if (category.equals(wakeLock.getCategory())) {
177                 wakeLocks.add(wakeLock);
178             }
179         }
180         return wakeLocks;
181     }
182 
183     /**
184      * Get a list of {@link WakelockInfoItem} .
185      */
getWakeLocks()186     public List<WakelockInfoItem> getWakeLocks() {
187         LinkedList<WakelockInfoItem> wakeLocks = new LinkedList<WakelockInfoItem>();
188 
189         for (WakelockInfoItem wakeLock : mWakeLocks) {
190             wakeLocks.add(wakeLock);
191         }
192         return wakeLocks;
193     }
194 
195     /**
196      * {@inheritDoc}
197      */
198     @Override
merge(IItem other)199     public IItem merge(IItem other) throws ConflictingItemException {
200         throw new ConflictingItemException("Wakelock items cannot be merged");
201     }
202 
203     /**
204      * {@inheritDoc}
205      */
206     @Override
isConsistent(IItem other)207     public boolean isConsistent(IItem other) {
208         return false;
209     }
210 
211     /**
212      * {@inheritDoc}
213      */
214     @Override
toJson()215     public JSONObject toJson() {
216         JSONObject object = new JSONObject();
217         if (mWakeLocks != null) {
218             try {
219                 JSONArray wakeLocks = new JSONArray();
220                 for (WakelockInfoItem wakeLock : mWakeLocks) {
221                     wakeLocks.put(wakeLock.toJson());
222                 }
223                 object.put(WAKELOCKS, wakeLocks);
224             } catch (JSONException e) {
225                 // Ignore
226             }
227         }
228         return object;
229     }
230 }
231