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