• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright 2017 The Chromium Authors
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 #ifndef COMPONENTS_METRICS_SYSTEM_SESSION_ANALYZER_SYSTEM_SESSION_ANALYZER_WIN_H_
6 #define COMPONENTS_METRICS_SYSTEM_SESSION_ANALYZER_SYSTEM_SESSION_ANALYZER_WIN_H_
7 
8 #include <windows.h>
9 #include <winevt.h>
10 
11 #include <map>
12 #include <memory>
13 #include <utility>
14 #include <vector>
15 
16 #include "base/gtest_prod_util.h"
17 #include "base/time/time.h"
18 
19 namespace metrics {
20 
21 // Analyzes system session events for unclean sessions. Initialization is
22 // expensive and therefore done lazily, as the analyzer is instantiated before
23 // knowing whether it will be used.
24 class SystemSessionAnalyzer {
25  public:
26   enum Status {
27     CLEAN = 0,
28     UNCLEAN = 1,
29     OUTSIDE_RANGE = 2,
30     INITIALIZE_FAILED = 3,
31     FETCH_EVENTS_FAILED = 4,
32     PROCESS_SESSION_FAILED = 5,
33     INSUFFICIENT_DATA = 6,
34   };
35 
36   // Track internal details of what went wrong.
37   enum class ExtendedStatus {
38     NO_FAILURE = 0,
39     RENDER_EVENT_FAILURE = 1,
40     ATTRIBUTE_CNT_MISMATCH = 2,
41     EXPECTED_INT16_TYPE = 3,
42     EXPECTED_FILETIME_TYPE = 4,
43     RETRIEVE_EVENTS_FAILURE = 5,
44     GET_EVENT_INFO_FAILURE = 6,
45     EVTQUERY_FAILED = 7,
46     CREATE_RENDER_CONTEXT_FAILURE = 8,
47     FETCH_EVENTS_FAILURE = 9,
48     EVENT_COUNT_MISMATCH = 10,
49     SESSION_START_MISMATCH = 11,
50     COVERAGE_START_ORDER_FAILURE = 12,
51     EVENT_ORDER_FAILURE = 13,
52     UNEXPECTED_START_EVENT_TYPE = 14,
53     UNEXPECTED_END_EVENT_TYPE = 15,
54   };
55 
56   ExtendedStatus GetExtendedFailureStatus() const;
57   // Set an extended failure status code for easier diagnosing of test failures.
58   // The first extended status code is retained.
59   void SetExtendedFailureStatus(ExtendedStatus);
60 
61   // Minimal information about a log event.
62   struct EventInfo {
63     uint16_t event_id;
64     base::Time event_time;
65   };
66 
67   // Creates a SystemSessionAnalyzer that will analyze system sessions based on
68   // events pertaining to as many as |max_session_cnt| of the most recent system
69   // sessions.
70   explicit SystemSessionAnalyzer(uint32_t max_session_cnt);
71 
72   SystemSessionAnalyzer(const SystemSessionAnalyzer&) = delete;
73   SystemSessionAnalyzer& operator=(const SystemSessionAnalyzer&) = delete;
74 
75   virtual ~SystemSessionAnalyzer();
76 
77   // Returns an analysis status for the system session that contains
78   // |timestamp|.
79   virtual Status IsSessionUnclean(base::Time timestamp);
80 
81  protected:
82   // Queries for the next |requested_events|. On success, returns true and
83   // |event_infos| contains up to |requested_events| events ordered from newest
84   // to oldest.
85   // Returns false otherwise. Virtual for unit testing.
86   virtual bool FetchEvents(size_t requested_events,
87                            std::vector<EventInfo>* event_infos);
88 
89  private:
90   struct EvtHandleCloser {
91     using pointer = EVT_HANDLE;
operatorEvtHandleCloser92     void operator()(EVT_HANDLE handle) const {
93       if (handle)
94         ::EvtClose(handle);
95     }
96   };
97   using EvtHandle = std::unique_ptr<EVT_HANDLE, EvtHandleCloser>;
98 
99   FRIEND_TEST_ALL_PREFIXES(SystemSessionAnalyzerTest, FetchEvents);
100 
101   bool EnsureInitialized();
102   bool EnsureHandlesOpened();
103   bool Initialize();
104   // Validates that |end| and |start| have sane event IDs and event times.
105   // Updates |coverage_start_| and adds the session to unclean_sessions_
106   // as appropriate.
107   bool ProcessSession(const EventInfo& end, const EventInfo& start);
108 
109   bool GetEventInfo(EVT_HANDLE context,
110                     EVT_HANDLE event,
111                     SystemSessionAnalyzer::EventInfo* info);
112   EvtHandle CreateRenderContext();
113 
114   // The maximal number of sessions to query events for.
115   uint32_t max_session_cnt_;
116   uint32_t sessions_queried_;
117 
118   bool initialized_ = false;
119   bool init_success_ = false;
120 
121   // A handle to the query, valid after a successful initialize.
122   EvtHandle query_handle_;
123   // A handle to the event render context, valid after a successful initialize.
124   EvtHandle render_context_;
125 
126   // Information about unclean sessions: start time to session duration.
127   std::map<base::Time, base::TimeDelta> unclean_sessions_;
128 
129   // Timestamp of the oldest event.
130   base::Time coverage_start_;
131 
132   // Track details of what failures occurred.
133   ExtendedStatus extended_status_ = ExtendedStatus::NO_FAILURE;
134 };
135 
136 }  // namespace metrics
137 
138 #endif  // COMPONENTS_METRICS_SYSTEM_SESSION_ANALYZER_SYSTEM_SESSION_ANALYZER_WIN_H_
139