1 // Copyright 2015 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #ifndef COMPONENTS_MEMORY_PRESSURE_MEMORY_PRESSURE_STATS_COLLECTOR_H_
6 #define COMPONENTS_MEMORY_PRESSURE_MEMORY_PRESSURE_STATS_COLLECTOR_H_
8 #include "base/time/time.h"
9 #include "components/memory_pressure/memory_pressure_listener.h"
15 namespace memory_pressure
{
17 // Enumeration of UMA memory pressure levels. The pressure level enum defined in
18 // MemoryPressureListener is non-contiguous. This enum is a contiguous version
19 // of that for use with UMA. Both it and histograms.xml must be kept in sync
20 // with the MemoryPressureListener enum. Included in the header so that
21 // UMA_MEMORY_PRESSURE_LEVEL_COUNT is available.
22 enum MemoryPressureLevelUMA
{
23 UMA_MEMORY_PRESSURE_LEVEL_NONE
= 0,
24 UMA_MEMORY_PRESSURE_LEVEL_MODERATE
= 1,
25 UMA_MEMORY_PRESSURE_LEVEL_CRITICAL
= 2,
26 // This must be the last value in the enum.
27 UMA_MEMORY_PRESSURE_LEVEL_COUNT
,
30 // Enumeration of UMA pressure level changes. This needs to be kept in sync
31 // with histograms.xml and the memory pressure levels defined in
32 // MemoryPressureListener. Exposed for unittesting.
33 enum MemoryPressureLevelChangeUMA
{
34 UMA_MEMORY_PRESSURE_LEVEL_CHANGE_NONE_TO_MODERATE
= 0,
35 UMA_MEMORY_PRESSURE_LEVEL_CHANGE_NONE_TO_CRITICAL
= 1,
36 UMA_MEMORY_PRESSURE_LEVEL_CHANGE_MODERATE_TO_CRITICAL
= 2,
37 UMA_MEMORY_PRESSURE_LEVEL_CHANGE_CRITICAL_TO_MODERATE
= 3,
38 UMA_MEMORY_PRESSURE_LEVEL_CHANGE_CRITICAL_TO_NONE
= 4,
39 UMA_MEMORY_PRESSURE_LEVEL_CHANGE_MODERATE_TO_NONE
= 5,
40 // This must be the last value in the enum.
41 UMA_MEMORY_PRESSURE_LEVEL_CHANGE_COUNT
44 // Class that is responsible for collecting and eventually reporting memory
45 // pressure statistics. Contributes to the "Memory.PressureLevel" and
46 // "Memory.PressureLevelChanges" histograms.
48 // On platforms with a polling memory pressure implementation the
49 // UpdateStatistics function will be invoked every time the pressure is polled.
50 // On non-polling platforms (Mac, Android) it will be invoked on a periodic
51 // timer, and at the moment of pressure level changes.
52 class MemoryPressureStatsCollector
{
54 using MemoryPressureLevel
= MemoryPressureListener::MemoryPressureLevel
;
56 // The provided |tick_clock| must outlive this class.
57 MemoryPressureStatsCollector(base::TickClock
* tick_clock
);
59 // This is to be called periodically to ensure that up to date statistics
60 // have been reported.
61 void UpdateStatistics(MemoryPressureLevel current_pressure_level
);
64 friend class TestMemoryPressureStatsCollector
;
66 // Helper functions for delivering collected statistics.
67 static void ReportCumulativeTime(MemoryPressureLevel pressure_level
,
69 static void ReportLevelChange(MemoryPressureLevel old_pressure_level
,
70 MemoryPressureLevel new_pressure_level
);
72 // The tick clock in use. This class is intended to be owned by a class with
73 // a tick clock, and ownership remains there. Also intended as a test seam.
74 base::TickClock
* tick_clock_
;
76 // Buckets of time that have been spent in different pressure levels, but
77 // not yet reported. At every call to UpdateStatistics these buckets will be
78 // drained of as many 'full' seconds of time as possible and reported via
79 // UMA. The remaining time (< 1000 ms) will be left in the bucket to be rolled
80 // into a later UMA report.
81 base::TimeDelta unreported_cumulative_time_
[UMA_MEMORY_PRESSURE_LEVEL_COUNT
];
83 // The last observed pressure level and the time at which it was observed, and
84 // the time when this pressure level started.
85 MemoryPressureLevel last_pressure_level_
;
86 base::TimeTicks last_update_time_
;
88 DISALLOW_COPY_AND_ASSIGN(MemoryPressureStatsCollector
);
91 } // namespace memory_pressure
93 #endif // COMPONENTS_MEMORY_PRESSURE_MEMORY_PRESSURE_STATS_COLLECTOR_H_