OLD | NEW |
1 /* | 1 /* |
2 * Copyright 2015 The WebRTC Project Authors. All rights reserved. | 2 * Copyright 2015 The WebRTC Project Authors. All rights reserved. |
3 * | 3 * |
4 * Use of this source code is governed by a BSD-style license | 4 * Use of this source code is governed by a BSD-style license |
5 * that can be found in the LICENSE file in the root of the source | 5 * that can be found in the LICENSE file in the root of the source |
6 * tree. An additional intellectual property rights grant can be found | 6 * tree. An additional intellectual property rights grant can be found |
7 * in the file PATENTS. All contributing project authors may | 7 * in the file PATENTS. All contributing project authors may |
8 * be found in the AUTHORS file in the root of the source tree. | 8 * be found in the AUTHORS file in the root of the source tree. |
9 */ | 9 */ |
10 | 10 |
11 package org.appspot.apprtc; | 11 package org.appspot.apprtc; |
12 | 12 |
13 import android.content.Context; | 13 import android.content.Context; |
14 import android.content.Intent; | 14 import android.content.Intent; |
15 import android.content.IntentFilter; | 15 import android.content.IntentFilter; |
16 import android.os.BatteryManager; | 16 import android.os.BatteryManager; |
17 import android.os.SystemClock; | 17 import android.os.SystemClock; |
18 import android.util.Log; | 18 import android.util.Log; |
19 | 19 |
20 import java.io.BufferedReader; | 20 import java.io.BufferedReader; |
21 import java.io.FileNotFoundException; | 21 import java.io.FileNotFoundException; |
22 import java.io.FileReader; | 22 import java.io.FileReader; |
23 import java.io.IOException; | 23 import java.io.IOException; |
24 import java.util.Arrays; | 24 import java.util.Arrays; |
25 import java.util.Scanner; | 25 import java.util.Scanner; |
26 | 26 import java.util.concurrent.Executors; |
27 import org.appspot.apprtc.util.LooperExecutor; | 27 import java.util.concurrent.ScheduledExecutorService; |
| 28 import java.util.concurrent.TimeUnit; |
28 | 29 |
29 /** | 30 /** |
30 * Simple CPU monitor. The caller creates a CpuMonitor object which can then | 31 * Simple CPU monitor. The caller creates a CpuMonitor object which can then |
31 * be used via sampleCpuUtilization() to collect the percentual use of the | 32 * be used via sampleCpuUtilization() to collect the percentual use of the |
32 * cumulative CPU capacity for all CPUs running at their nominal frequency. 3 | 33 * cumulative CPU capacity for all CPUs running at their nominal frequency. 3 |
33 * values are generated: (1) getCpuCurrent() returns the use since the last | 34 * values are generated: (1) getCpuCurrent() returns the use since the last |
34 * sampleCpuUtilization(), (2) getCpuAvg3() returns the use since 3 prior | 35 * sampleCpuUtilization(), (2) getCpuAvg3() returns the use since 3 prior |
35 * calls, and (3) getCpuAvgAll() returns the use over all SAMPLE_SAVE_NUMBER | 36 * calls, and (3) getCpuAvgAll() returns the use over all SAMPLE_SAVE_NUMBER |
36 * calls. | 37 * calls. |
37 * | 38 * |
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
78 private final Context appContext; | 79 private final Context appContext; |
79 // User CPU usage at current frequency. | 80 // User CPU usage at current frequency. |
80 private final MovingAverage userCpuUsage; | 81 private final MovingAverage userCpuUsage; |
81 // System CPU usage at current frequency. | 82 // System CPU usage at current frequency. |
82 private final MovingAverage systemCpuUsage; | 83 private final MovingAverage systemCpuUsage; |
83 // Total CPU usage relative to maximum frequency. | 84 // Total CPU usage relative to maximum frequency. |
84 private final MovingAverage totalCpuUsage; | 85 private final MovingAverage totalCpuUsage; |
85 // CPU frequency in percentage from maximum. | 86 // CPU frequency in percentage from maximum. |
86 private final MovingAverage frequencyScale; | 87 private final MovingAverage frequencyScale; |
87 | 88 |
88 private LooperExecutor executor; | 89 private ScheduledExecutorService executor; |
89 private long lastStatLogTimeMs; | 90 private long lastStatLogTimeMs; |
90 private long[] cpuFreqMax; | 91 private long[] cpuFreqMax; |
91 private int cpusPresent; | 92 private int cpusPresent; |
92 private int actualCpusPresent; | 93 private int actualCpusPresent; |
93 private boolean initialized; | 94 private boolean initialized; |
94 private boolean cpuOveruse; | 95 private boolean cpuOveruse; |
95 private String[] maxPath; | 96 private String[] maxPath; |
96 private String[] curPath; | 97 private String[] curPath; |
97 private double[] curFreqScales; | 98 private double[] curFreqScales; |
98 private ProcStat lastProcStat; | 99 private ProcStat lastProcStat; |
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
152 | 153 |
153 public CpuMonitor(Context context) { | 154 public CpuMonitor(Context context) { |
154 Log.d(TAG, "CpuMonitor ctor."); | 155 Log.d(TAG, "CpuMonitor ctor."); |
155 appContext = context.getApplicationContext(); | 156 appContext = context.getApplicationContext(); |
156 userCpuUsage = new MovingAverage(MOVING_AVERAGE_SAMPLES); | 157 userCpuUsage = new MovingAverage(MOVING_AVERAGE_SAMPLES); |
157 systemCpuUsage = new MovingAverage(MOVING_AVERAGE_SAMPLES); | 158 systemCpuUsage = new MovingAverage(MOVING_AVERAGE_SAMPLES); |
158 totalCpuUsage = new MovingAverage(MOVING_AVERAGE_SAMPLES); | 159 totalCpuUsage = new MovingAverage(MOVING_AVERAGE_SAMPLES); |
159 frequencyScale = new MovingAverage(MOVING_AVERAGE_SAMPLES); | 160 frequencyScale = new MovingAverage(MOVING_AVERAGE_SAMPLES); |
160 lastStatLogTimeMs = SystemClock.elapsedRealtime(); | 161 lastStatLogTimeMs = SystemClock.elapsedRealtime(); |
161 | 162 |
162 executor = new LooperExecutor(); | |
163 executor.requestStart(); | |
164 scheduleCpuUtilizationTask(); | 163 scheduleCpuUtilizationTask(); |
165 } | 164 } |
166 | 165 |
167 public void release() { | |
168 if (executor != null) { | |
169 Log.d(TAG, "release"); | |
170 executor.cancelScheduledTasks(); | |
171 executor.requestStop(); | |
172 executor = null; | |
173 } | |
174 } | |
175 | |
176 public void pause() { | 166 public void pause() { |
177 if (executor != null) { | 167 if (executor != null) { |
178 Log.d(TAG, "pause"); | 168 Log.d(TAG, "pause"); |
179 executor.cancelScheduledTasks(); | 169 executor.shutdownNow(); |
| 170 executor = null; |
180 } | 171 } |
181 } | 172 } |
182 | 173 |
183 public void resume() { | 174 public void resume() { |
184 if (executor != null) { | 175 Log.d(TAG, "resume"); |
185 Log.d(TAG, "resume"); | 176 resetStat(); |
186 resetStat(); | 177 scheduleCpuUtilizationTask(); |
187 scheduleCpuUtilizationTask(); | |
188 } | |
189 } | 178 } |
190 | 179 |
191 public synchronized void reset() { | 180 public synchronized void reset() { |
192 if (executor != null) { | 181 if (executor != null) { |
193 Log.d(TAG, "reset"); | 182 Log.d(TAG, "reset"); |
194 resetStat(); | 183 resetStat(); |
195 cpuOveruse = false; | 184 cpuOveruse = false; |
196 } | 185 } |
197 } | 186 } |
198 | 187 |
199 public synchronized int getCpuUsageCurrent() { | 188 public synchronized int getCpuUsageCurrent() { |
200 return doubleToPercent(userCpuUsage.getCurrent() + systemCpuUsage.getCurrent
()); | 189 return doubleToPercent(userCpuUsage.getCurrent() + systemCpuUsage.getCurrent
()); |
201 } | 190 } |
202 | 191 |
203 public synchronized int getCpuUsageAverage() { | 192 public synchronized int getCpuUsageAverage() { |
204 return doubleToPercent(userCpuUsage.getAverage() + systemCpuUsage.getAverage
()); | 193 return doubleToPercent(userCpuUsage.getAverage() + systemCpuUsage.getAverage
()); |
205 } | 194 } |
206 | 195 |
207 public synchronized int getFrequencyScaleAverage() { | 196 public synchronized int getFrequencyScaleAverage() { |
208 return doubleToPercent(frequencyScale.getAverage()); | 197 return doubleToPercent(frequencyScale.getAverage()); |
209 } | 198 } |
210 | 199 |
211 private void scheduleCpuUtilizationTask() { | 200 private void scheduleCpuUtilizationTask() { |
212 executor.cancelScheduledTasks(); | 201 if (executor != null) { |
| 202 executor.shutdownNow(); |
| 203 executor = null; |
| 204 } |
| 205 |
| 206 executor = Executors.newSingleThreadScheduledExecutor(); |
213 executor.scheduleAtFixedRate(new Runnable() { | 207 executor.scheduleAtFixedRate(new Runnable() { |
214 @Override | 208 @Override |
215 public void run() { | 209 public void run() { |
216 cpuUtilizationTask(); | 210 cpuUtilizationTask(); |
217 } | 211 } |
218 }, CPU_STAT_SAMPLE_PERIOD_MS); | 212 }, 0, CPU_STAT_SAMPLE_PERIOD_MS, TimeUnit.MILLISECONDS); |
219 } | 213 } |
220 | 214 |
221 private void cpuUtilizationTask() { | 215 private void cpuUtilizationTask() { |
222 boolean cpuMonitorAvailable = sampleCpuUtilization(); | 216 boolean cpuMonitorAvailable = sampleCpuUtilization(); |
223 if (cpuMonitorAvailable | 217 if (cpuMonitorAvailable |
224 && SystemClock.elapsedRealtime() - lastStatLogTimeMs >= CPU_STAT_LOG_PER
IOD_MS) { | 218 && SystemClock.elapsedRealtime() - lastStatLogTimeMs >= CPU_STAT_LOG_PER
IOD_MS) { |
225 lastStatLogTimeMs = SystemClock.elapsedRealtime(); | 219 lastStatLogTimeMs = SystemClock.elapsedRealtime(); |
226 String statString = getStatString(); | 220 String statString = getStatString(); |
227 Log.d(TAG, statString); | 221 Log.d(TAG, statString); |
228 } | 222 } |
(...skipping 274 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
503 } catch (FileNotFoundException e) { | 497 } catch (FileNotFoundException e) { |
504 Log.e(TAG, "Cannot open /proc/stat for reading", e); | 498 Log.e(TAG, "Cannot open /proc/stat for reading", e); |
505 return null; | 499 return null; |
506 } catch (IOException e) { | 500 } catch (IOException e) { |
507 Log.e(TAG, "Problems reading /proc/stat", e); | 501 Log.e(TAG, "Problems reading /proc/stat", e); |
508 return null; | 502 return null; |
509 } | 503 } |
510 return new ProcStat(userTime, systemTime, idleTime); | 504 return new ProcStat(userTime, systemTime, idleTime); |
511 } | 505 } |
512 } | 506 } |
OLD | NEW |