Cast: Stop logging kVideoFrameSentToEncoder and rename a couple events.
[chromium-blink-merge.git] / chrome / browser / chrome_elf_init_win.cc
blob79465b8eef99940cdc21294cd3e76db0a5cd66c1
1 // Copyright 2014 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 #include "base/bind.h"
6 #include "base/metrics/field_trial.h"
7 #include "base/metrics/histogram.h"
8 #include "base/metrics/sparse_histogram.h"
9 #include "base/strings/utf_string_conversions.h"
10 #include "base/win/registry.h"
11 #include "chrome/browser/chrome_elf_init_win.h"
12 #include "chrome_elf/blacklist/blacklist.h"
13 #include "chrome_elf/chrome_elf_constants.h"
14 #include "chrome_elf/dll_hash/dll_hash.h"
15 #include "content/public/browser/browser_thread.h"
16 #include "version.h" // NOLINT
18 namespace {
20 const char kBrowserBlacklistTrialName[] = "BrowserBlacklist";
21 const char kBrowserBlacklistTrialEnabledGroupName[] = "Enabled";
23 // How long to wait, in seconds, before reporting for the second (and last
24 // time), what dlls were blocked from the browser process.
25 const int kBlacklistReportingDelaySec = 600;
27 // This enum is used to define the buckets for an enumerated UMA histogram.
28 // Hence,
29 // (a) existing enumerated constants should never be deleted or reordered, and
30 // (b) new constants should only be appended in front of
31 // BLACKLIST_SETUP_EVENT_MAX.
32 enum BlacklistSetupEventType {
33 // The blacklist beacon has placed to enable the browser blacklisting.
34 BLACKLIST_SETUP_ENABLED = 0,
36 // The blacklist was successfully enabled.
37 BLACKLIST_SETUP_RAN_SUCCESSFULLY,
39 // The blacklist setup code failed to execute.
40 BLACKLIST_SETUP_FAILED,
42 // The blacklist thunk setup code failed to execute.
43 BLACKLIST_THUNK_SETUP_FAILED,
45 // The blacklist interception code failed to execute.
46 BLACKLIST_INTERCEPTION_FAILED,
48 // Always keep this at the end.
49 BLACKLIST_SETUP_EVENT_MAX,
52 void RecordBlacklistSetupEvent(BlacklistSetupEventType blacklist_setup_event) {
53 UMA_HISTOGRAM_ENUMERATION("Blacklist.Setup",
54 blacklist_setup_event,
55 BLACKLIST_SETUP_EVENT_MAX);
58 // Report which DLLs were prevented from being loaded.
59 void ReportSuccessfulBlocks() {
60 // Figure out how many dlls were blocked.
61 int num_blocked_dlls = 0;
62 blacklist::SuccessfullyBlocked(NULL, &num_blocked_dlls);
64 if (num_blocked_dlls == 0)
65 return;
67 // Now retrieve the list of blocked dlls.
68 std::vector<const wchar_t*> blocked_dlls(num_blocked_dlls);
69 blacklist::SuccessfullyBlocked(&blocked_dlls[0], &num_blocked_dlls);
71 // Send up the hashes of the blocked dlls via UMA.
72 for (size_t i = 0; i < blocked_dlls.size(); ++i) {
73 std::string dll_name_utf8;
74 base::WideToUTF8(blocked_dlls[i], wcslen(blocked_dlls[i]), &dll_name_utf8);
75 int uma_hash = DllNameToHash(dll_name_utf8);
77 UMA_HISTOGRAM_SPARSE_SLOWLY("Blacklist.Blocked", uma_hash);
81 } // namespace
83 void InitializeChromeElf() {
84 if (base::FieldTrialList::FindFullName(kBrowserBlacklistTrialName) ==
85 kBrowserBlacklistTrialEnabledGroupName) {
86 BrowserBlacklistBeaconSetup();
87 } else {
88 // Disable the blacklist for all future runs by removing the beacon.
89 base::win::RegKey blacklist_registry_key(HKEY_CURRENT_USER);
90 blacklist_registry_key.DeleteKey(blacklist::kRegistryBeaconPath);
93 // Report all successful blacklist interceptions.
94 ReportSuccessfulBlocks();
96 // Schedule another task to report all sucessful interceptions later.
97 // This time delay should be long enough to catch any dlls that attempt to
98 // inject after Chrome has started up.
99 content::BrowserThread::PostDelayedTask(
100 content::BrowserThread::UI,
101 FROM_HERE,
102 base::Bind(&ReportSuccessfulBlocks),
103 base::TimeDelta::FromSeconds(kBlacklistReportingDelaySec));
106 void BrowserBlacklistBeaconSetup() {
107 base::win::RegKey blacklist_registry_key(HKEY_CURRENT_USER,
108 blacklist::kRegistryBeaconPath,
109 KEY_QUERY_VALUE | KEY_SET_VALUE);
111 // No point in trying to continue if the registry key isn't valid.
112 if (!blacklist_registry_key.Valid())
113 return;
115 // Record the results of the last blacklist setup.
116 DWORD blacklist_state = blacklist::BLACKLIST_STATE_MAX;
117 blacklist_registry_key.ReadValueDW(blacklist::kBeaconState, &blacklist_state);
119 if (blacklist_state == blacklist::BLACKLIST_ENABLED) {
120 RecordBlacklistSetupEvent(BLACKLIST_SETUP_RAN_SUCCESSFULLY);
121 } else {
122 switch (blacklist_state) {
123 case blacklist::BLACKLIST_SETUP_RUNNING:
124 RecordBlacklistSetupEvent(BLACKLIST_SETUP_FAILED);
125 break;
126 case blacklist::BLACKLIST_THUNK_SETUP:
127 RecordBlacklistSetupEvent(BLACKLIST_THUNK_SETUP_FAILED);
128 break;
129 case blacklist::BLACKLIST_INTERCEPTING:
130 RecordBlacklistSetupEvent(BLACKLIST_INTERCEPTION_FAILED);
131 break;
134 // Since some part of the blacklist failed, mark it as disabled
135 // for this version.
136 if (blacklist_state != blacklist::BLACKLIST_DISABLED) {
137 blacklist_registry_key.WriteValue(blacklist::kBeaconState,
138 blacklist::BLACKLIST_DISABLED);
142 // Find the last recorded blacklist version.
143 base::string16 blacklist_version;
144 blacklist_registry_key.ReadValue(blacklist::kBeaconVersion,
145 &blacklist_version);
147 if (blacklist_version != TEXT(CHROME_VERSION_STRING)) {
148 // The blacklist hasn't been enabled for this version yet, so enable it.
149 LONG set_version = blacklist_registry_key.WriteValue(
150 blacklist::kBeaconVersion,
151 TEXT(CHROME_VERSION_STRING));
153 LONG set_state = blacklist_registry_key.WriteValue(
154 blacklist::kBeaconState,
155 blacklist::BLACKLIST_ENABLED);
157 // Only report the blacklist as getting setup when both registry writes
158 // succeed, since otherwise the blacklist wasn't properly setup.
159 if (set_version == ERROR_SUCCESS && set_state == ERROR_SUCCESS)
160 RecordBlacklistSetupEvent(BLACKLIST_SETUP_ENABLED);