Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(157)

Side by Side Diff: chrome/browser/chromeos/system/statistics_provider.cc

Issue 25112004: Move statistics_provider to chromeos/system (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Add comments Created 7 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
(Empty)
1 // Copyright (c) 2012 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.
4
5 #include "chrome/browser/chromeos/system/statistics_provider.h"
6
7 #include "base/bind.h"
8 #include "base/command_line.h"
9 #include "base/files/file_path.h"
10 #include "base/logging.h"
11 #include "base/memory/singleton.h"
12 #include "base/path_service.h"
13 #include "base/synchronization/waitable_event.h"
14 #include "base/sys_info.h"
15 #include "base/threading/thread_restrictions.h"
16 #include "base/time/time.h"
17 #include "chromeos/app_mode/kiosk_oem_manifest_parser.h"
18 #include "chromeos/chromeos_constants.h"
19 #include "chromeos/chromeos_switches.h"
20 #include "chromeos/system/name_value_pairs_parser.h"
21 #include "content/public/browser/browser_thread.h"
22
23 using content::BrowserThread;
24
25 namespace chromeos {
26 namespace system {
27 namespace {
28
29 // Path to the tool used to get system info, and delimiters for the output
30 // format of the tool.
31 const char* kCrosSystemTool[] = { "/usr/bin/crossystem" };
32 const char kCrosSystemEq[] = "=";
33 const char kCrosSystemDelim[] = "\n";
34 const char kCrosSystemCommentDelim[] = "#";
35 const char kCrosSystemUnknownValue[] = "(error)";
36
37 const char kHardwareClassCrosSystemKey[] = "hwid";
38 const char kHardwareClassKey[] = "hardware_class";
39 const char kUnknownHardwareClass[] = "unknown";
40
41 // File to get machine hardware info from, and key/value delimiters of
42 // the file.
43 // /tmp/machine-info is generated by platform/init/chromeos_startup.
44 const char kMachineHardwareInfoFile[] = "/tmp/machine-info";
45 const char kMachineHardwareInfoEq[] = "=";
46 const char kMachineHardwareInfoDelim[] = " \n";
47
48 // File to get ECHO coupon info from, and key/value delimiters of
49 // the file.
50 const char kEchoCouponFile[] = "/var/cache/echo/vpd_echo.txt";
51 const char kEchoCouponEq[] = "=";
52 const char kEchoCouponDelim[] = "\n";
53
54 // File to get VPD info from, and key/value delimiters of the file.
55 const char kVpdFile[] = "/var/log/vpd_2.0.txt";
56 const char kVpdEq[] = "=";
57 const char kVpdDelim[] = "\n";
58
59 // Timeout that we should wait for statistics to get loaded
60 const int kTimeoutSecs = 3;
61
62 // The location of OEM manifest file used to trigger OOBE flow for kiosk mode.
63 const CommandLine::CharType kOemManifestFilePath[] =
64 FILE_PATH_LITERAL("/usr/share/oem/oobe/manifest.json");
65
66 } // namespace
67
68 // Key values for GetMachineStatistic()/GetMachineFlag() calls.
69 const char kDevSwitchBootMode[] = "devsw_boot";
70 const char kHardwareClass[] = "hardware_class";
71 const char kOffersCouponCodeKey[] = "ubind_attribute";
72 const char kOffersGroupCodeKey[] = "gbind_attribute";
73 const char kOemCanExitEnterpriseEnrollmentKey[] =
74 "oem_can_exit_enrollment";
75 const char kOemDeviceRequisitionKey[] =
76 "oem_device_requisition";
77 const char kOemIsEnterpriseManagedKey[] =
78 "oem_enterprise_managed";
79 const char kOemKeyboardDrivenOobeKey[] =
80 "oem_keyboard_driven_oobe";
81
82 // The StatisticsProvider implementation used in production.
83 class StatisticsProviderImpl : public StatisticsProvider {
84 public:
85 // StatisticsProvider implementation:
86 virtual void Init() OVERRIDE;
87 virtual void StartLoadingMachineStatistics() OVERRIDE;
88 virtual bool GetMachineStatistic(const std::string& name,
89 std::string* result) OVERRIDE;
90 virtual bool GetMachineFlag(const std::string& name,
91 bool* result) OVERRIDE;
92 virtual void LoadOemManifest() OVERRIDE;
93
94 static StatisticsProviderImpl* GetInstance();
95
96 protected:
97 StatisticsProviderImpl();
98 void LoadOemManifestFromFile(const base::FilePath& file);
99
100 private:
101 typedef std::map<std::string, bool> MachineFlags;
102 friend struct DefaultSingletonTraits<StatisticsProviderImpl>;
103
104 // Loads the machine statistcs by examining the system.
105 void LoadMachineStatistics();
106
107 bool initialized_;
108 bool load_statistics_started_;
109 NameValuePairsParser::NameValueMap machine_info_;
110 MachineFlags machine_flags_;
111 base::WaitableEvent on_statistics_loaded_;
112
113 DISALLOW_COPY_AND_ASSIGN(StatisticsProviderImpl);
114 };
115
116 void StatisticsProviderImpl::Init() {
117 DCHECK(!initialized_);
118 initialized_ = true;
119 }
120
121 bool StatisticsProviderImpl::GetMachineStatistic(
122 const std::string& name, std::string* result) {
123 CHECK(initialized_);
124 CHECK(load_statistics_started_)
125 << "GetMachineStatistic called before load started: " << name;
126
127 VLOG(1) << "Statistic is requested for " << name;
128 // Block if the statistics are not loaded yet. Per LOG(WARNING) below,
129 // the statistics are loaded before requested as of now. For regular
130 // sessions (i.e. not OOBE), statistics are first requested when the
131 // user is logging in so we have plenty of time to load the data
132 // beforehand.
133 //
134 // If you see the warning appeared for regular sessions, it probably
135 // means that there is new client code that uses the statistics in the
136 // very early stage of the browser startup. The statistic name should be
137 // helpful to identify the caller.
138 if (!on_statistics_loaded_.IsSignaled()) {
139 // http://crbug.com/125385
140 base::Time start_time = base::Time::Now();
141 base::ThreadRestrictions::ScopedAllowWait allow_wait;
142 on_statistics_loaded_.TimedWait(base::TimeDelta::FromSeconds(kTimeoutSecs));
143 base::TimeDelta dtime = base::Time::Now() - start_time;
144 if (!on_statistics_loaded_.IsSignaled()) {
145 LOG(ERROR) << "Statistics weren't loaded after waiting "
146 << dtime.InMilliseconds() << "ms. "
147 << "Requested statistic: " << name;
148 return false;
149 } else {
150 LOG(ERROR) << "Statistic loaded after waiting "
151 << dtime.InMilliseconds() << "ms. "
152 << "Requested statistic: " << name;
153 }
154 }
155
156 NameValuePairsParser::NameValueMap::iterator iter = machine_info_.find(name);
157 if (iter != machine_info_.end()) {
158 *result = iter->second;
159 return true;
160 }
161 return false;
162 }
163
164 bool StatisticsProviderImpl::GetMachineFlag(
165 const std::string& name, bool* result) {
166 MachineFlags::const_iterator iter = machine_flags_.find(name);
167 if (iter != machine_flags_.end()) {
168 *result = iter->second;
169 return true;
170 }
171
172 return false;
173 }
174
175 void StatisticsProviderImpl::LoadOemManifest() {
176 LoadOemManifestFromFile(base::FilePath(kOemManifestFilePath));
177 }
178
179 // manual_reset needs to be true, as we want to keep the signaled state.
180 StatisticsProviderImpl::StatisticsProviderImpl()
181 : initialized_(false),
182 load_statistics_started_(false),
183 on_statistics_loaded_(true /* manual_reset */,
184 false /* initially_signaled */) {
185 }
186
187 void StatisticsProviderImpl::StartLoadingMachineStatistics() {
188 DCHECK(initialized_);
189 DCHECK(!load_statistics_started_);
190 load_statistics_started_ = true;
191
192 VLOG(1) << "Started loading statistics";
193 BrowserThread::PostBlockingPoolTask(
194 FROM_HERE,
195 base::Bind(&StatisticsProviderImpl::LoadMachineStatistics,
196 base::Unretained(this)));
197 }
198
199 void StatisticsProviderImpl::LoadMachineStatistics() {
200 NameValuePairsParser parser(&machine_info_);
201
202 // Parse all of the key/value pairs from the crossystem tool.
203 if (!parser.ParseNameValuePairsFromTool(
204 arraysize(kCrosSystemTool), kCrosSystemTool, kCrosSystemEq,
205 kCrosSystemDelim, kCrosSystemCommentDelim)) {
206 LOG(WARNING) << "There were errors parsing the output of "
207 << kCrosSystemTool << ".";
208 }
209
210 // Ensure that the hardware class key is present with the expected
211 // key name, and if it couldn't be retrieved, that the value is "unknown".
212 std::string hardware_class = machine_info_[kHardwareClassCrosSystemKey];
213 if (hardware_class.empty() || hardware_class == kCrosSystemUnknownValue)
214 machine_info_[kHardwareClassKey] = kUnknownHardwareClass;
215 else
216 machine_info_[kHardwareClassKey] = hardware_class;
217
218 parser.GetNameValuePairsFromFile(base::FilePath(kMachineHardwareInfoFile),
219 kMachineHardwareInfoEq,
220 kMachineHardwareInfoDelim);
221 parser.GetNameValuePairsFromFile(base::FilePath(kEchoCouponFile),
222 kEchoCouponEq,
223 kEchoCouponDelim);
224 parser.GetNameValuePairsFromFile(base::FilePath(kVpdFile), kVpdEq, kVpdDelim);
225
226 // Finished loading the statistics.
227 on_statistics_loaded_.Signal();
228 VLOG(1) << "Finished loading statistics";
229 }
230
231 void StatisticsProviderImpl::LoadOemManifestFromFile(
232 const base::FilePath& file) {
233 KioskOemManifestParser::Manifest oem_manifest;
234 if (!KioskOemManifestParser::Load(file, &oem_manifest))
235 return;
236
237 machine_info_[kOemDeviceRequisitionKey] =
238 oem_manifest.device_requisition;
239 machine_flags_[kOemIsEnterpriseManagedKey] =
240 oem_manifest.enterprise_managed;
241 machine_flags_[kOemCanExitEnterpriseEnrollmentKey] =
242 oem_manifest.can_exit_enrollment;
243 machine_flags_[kOemKeyboardDrivenOobeKey] =
244 oem_manifest.keyboard_driven_oobe;
245 }
246
247 StatisticsProviderImpl* StatisticsProviderImpl::GetInstance() {
248 return Singleton<StatisticsProviderImpl,
249 DefaultSingletonTraits<StatisticsProviderImpl> >::get();
250 }
251
252 // The stub StatisticsProvider implementation used on Linux desktop.
253 class StatisticsProviderStubImpl : public StatisticsProviderImpl {
254 public:
255 // StatisticsProvider implementation:
256 virtual void Init() OVERRIDE {}
257
258 virtual void StartLoadingMachineStatistics() OVERRIDE {}
259
260 virtual bool GetMachineStatistic(const std::string& name,
261 std::string* result) OVERRIDE {
262 if (name == "CHROMEOS_RELEASE_BOARD") {
263 // Note: syncer::GetSessionNameSynchronously() also uses the mechanism
264 // below to determine the CrOs release board. However, it cannot include
265 // statistics_provider.h and use this method because of the mutual
266 // dependency that creates between sync.gyp:sync and chrome.gyp:browser.
267 // TODO(rsimha): Update syncer::GetSessionNameSynchronously() if this code
268 // is ever moved into base/. See http://crbug.com/126732.
269 const CommandLine* command_line = CommandLine::ForCurrentProcess();
270 if (command_line->HasSwitch(chromeos::switches::kChromeOSReleaseBoard)) {
271 *result = command_line->
272 GetSwitchValueASCII(chromeos::switches::kChromeOSReleaseBoard);
273 return true;
274 }
275 }
276 return false;
277 }
278
279 virtual void LoadOemManifest() OVERRIDE {
280 CommandLine* command_line = CommandLine::ForCurrentProcess();
281 if (!command_line->HasSwitch(switches::kAppOemManifestFile))
282 return;
283
284 LoadOemManifestFromFile(
285 command_line->GetSwitchValuePath(switches::kAppOemManifestFile));
286 }
287
288 static StatisticsProviderStubImpl* GetInstance() {
289 return Singleton<StatisticsProviderStubImpl,
290 DefaultSingletonTraits<StatisticsProviderStubImpl> >::get();
291 }
292
293 private:
294 friend struct DefaultSingletonTraits<StatisticsProviderStubImpl>;
295
296 StatisticsProviderStubImpl() {
297 }
298
299 DISALLOW_COPY_AND_ASSIGN(StatisticsProviderStubImpl);
300 };
301
302 StatisticsProvider* StatisticsProvider::GetInstance() {
303 if (base::SysInfo::IsRunningOnChromeOS()) {
304 return StatisticsProviderImpl::GetInstance();
305 } else {
306 return StatisticsProviderStubImpl::GetInstance();
307 }
308 }
309
310 } // namespace system
311 } // namespace chromeos
OLDNEW
« no previous file with comments | « chrome/browser/chromeos/system/statistics_provider.h ('k') | chrome/browser/metrics/metrics_service.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698