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

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: Rebase, fix DeviceManagement 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 // TODO(stevenjb): Thes should be made fatal once fixed. crbug.com/302798.
125 if (!load_statistics_started_) {
126 LOG(ERROR) << "GetMachineStatistic called before load started: " << name;
127 return false;
128 }
129
130 VLOG(1) << "Statistic is requested for " << name;
131 // Block if the statistics are not loaded yet. Per LOG(WARNING) below,
132 // the statistics are loaded before requested as of now. For regular
133 // sessions (i.e. not OOBE), statistics are first requested when the
134 // user is logging in so we have plenty of time to load the data
135 // beforehand.
136 //
137 // If you see the warning appeared for regular sessions, it probably
138 // means that there is new client code that uses the statistics in the
139 // very early stage of the browser startup. The statistic name should be
140 // helpful to identify the caller.
141 if (!on_statistics_loaded_.IsSignaled()) {
142 // http://crbug.com/125385
143 base::Time start_time = base::Time::Now();
144 base::ThreadRestrictions::ScopedAllowWait allow_wait;
145 on_statistics_loaded_.TimedWait(base::TimeDelta::FromSeconds(kTimeoutSecs));
146 base::TimeDelta dtime = base::Time::Now() - start_time;
147 if (!on_statistics_loaded_.IsSignaled()) {
148 LOG(ERROR) << "Statistics weren't loaded after waiting "
149 << dtime.InMilliseconds() << "ms. "
150 << "Requested statistic: " << name;
151 return false;
152 } else {
153 LOG(ERROR) << "Statistic loaded after waiting "
154 << dtime.InMilliseconds() << "ms. "
155 << "Requested statistic: " << name;
156 }
157 }
158
159 NameValuePairsParser::NameValueMap::iterator iter = machine_info_.find(name);
160 if (iter != machine_info_.end()) {
161 *result = iter->second;
162 return true;
163 }
164 return false;
165 }
166
167 bool StatisticsProviderImpl::GetMachineFlag(
168 const std::string& name, bool* result) {
169 MachineFlags::const_iterator iter = machine_flags_.find(name);
170 if (iter != machine_flags_.end()) {
171 *result = iter->second;
172 return true;
173 }
174
175 return false;
176 }
177
178 void StatisticsProviderImpl::LoadOemManifest() {
179 LoadOemManifestFromFile(base::FilePath(kOemManifestFilePath));
180 }
181
182 // manual_reset needs to be true, as we want to keep the signaled state.
183 StatisticsProviderImpl::StatisticsProviderImpl()
184 : initialized_(false),
185 load_statistics_started_(false),
186 on_statistics_loaded_(true /* manual_reset */,
187 false /* initially_signaled */) {
188 }
189
190 void StatisticsProviderImpl::StartLoadingMachineStatistics() {
191 DCHECK(initialized_);
192 DCHECK(!load_statistics_started_);
193 load_statistics_started_ = true;
194
195 VLOG(1) << "Started loading statistics";
196 BrowserThread::PostBlockingPoolTask(
197 FROM_HERE,
198 base::Bind(&StatisticsProviderImpl::LoadMachineStatistics,
199 base::Unretained(this)));
200 }
201
202 void StatisticsProviderImpl::LoadMachineStatistics() {
203 NameValuePairsParser parser(&machine_info_);
204
205 // Parse all of the key/value pairs from the crossystem tool.
206 if (!parser.ParseNameValuePairsFromTool(
207 arraysize(kCrosSystemTool), kCrosSystemTool, kCrosSystemEq,
208 kCrosSystemDelim, kCrosSystemCommentDelim)) {
209 LOG(WARNING) << "There were errors parsing the output of "
210 << kCrosSystemTool << ".";
211 }
212
213 // Ensure that the hardware class key is present with the expected
214 // key name, and if it couldn't be retrieved, that the value is "unknown".
215 std::string hardware_class = machine_info_[kHardwareClassCrosSystemKey];
216 if (hardware_class.empty() || hardware_class == kCrosSystemUnknownValue)
217 machine_info_[kHardwareClassKey] = kUnknownHardwareClass;
218 else
219 machine_info_[kHardwareClassKey] = hardware_class;
220
221 parser.GetNameValuePairsFromFile(base::FilePath(kMachineHardwareInfoFile),
222 kMachineHardwareInfoEq,
223 kMachineHardwareInfoDelim);
224 parser.GetNameValuePairsFromFile(base::FilePath(kEchoCouponFile),
225 kEchoCouponEq,
226 kEchoCouponDelim);
227 parser.GetNameValuePairsFromFile(base::FilePath(kVpdFile), kVpdEq, kVpdDelim);
228
229 // Finished loading the statistics.
230 on_statistics_loaded_.Signal();
231 VLOG(1) << "Finished loading statistics";
232 }
233
234 void StatisticsProviderImpl::LoadOemManifestFromFile(
235 const base::FilePath& file) {
236 KioskOemManifestParser::Manifest oem_manifest;
237 if (!KioskOemManifestParser::Load(file, &oem_manifest))
238 return;
239
240 machine_info_[kOemDeviceRequisitionKey] =
241 oem_manifest.device_requisition;
242 machine_flags_[kOemIsEnterpriseManagedKey] =
243 oem_manifest.enterprise_managed;
244 machine_flags_[kOemCanExitEnterpriseEnrollmentKey] =
245 oem_manifest.can_exit_enrollment;
246 machine_flags_[kOemKeyboardDrivenOobeKey] =
247 oem_manifest.keyboard_driven_oobe;
248 }
249
250 StatisticsProviderImpl* StatisticsProviderImpl::GetInstance() {
251 return Singleton<StatisticsProviderImpl,
252 DefaultSingletonTraits<StatisticsProviderImpl> >::get();
253 }
254
255 // The stub StatisticsProvider implementation used on Linux desktop.
256 class StatisticsProviderStubImpl : public StatisticsProviderImpl {
257 public:
258 // StatisticsProvider implementation:
259 virtual void Init() OVERRIDE {}
260
261 virtual void StartLoadingMachineStatistics() OVERRIDE {}
262
263 virtual bool GetMachineStatistic(const std::string& name,
264 std::string* result) OVERRIDE {
265 if (name == "CHROMEOS_RELEASE_BOARD") {
266 // Note: syncer::GetSessionNameSynchronously() also uses the mechanism
267 // below to determine the CrOs release board. However, it cannot include
268 // statistics_provider.h and use this method because of the mutual
269 // dependency that creates between sync.gyp:sync and chrome.gyp:browser.
270 // TODO(rsimha): Update syncer::GetSessionNameSynchronously() if this code
271 // is ever moved into base/. See http://crbug.com/126732.
272 const CommandLine* command_line = CommandLine::ForCurrentProcess();
273 if (command_line->HasSwitch(chromeos::switches::kChromeOSReleaseBoard)) {
274 *result = command_line->
275 GetSwitchValueASCII(chromeos::switches::kChromeOSReleaseBoard);
276 return true;
277 }
278 }
279 return false;
280 }
281
282 virtual void LoadOemManifest() OVERRIDE {
283 CommandLine* command_line = CommandLine::ForCurrentProcess();
284 if (!command_line->HasSwitch(switches::kAppOemManifestFile))
285 return;
286
287 LoadOemManifestFromFile(
288 command_line->GetSwitchValuePath(switches::kAppOemManifestFile));
289 }
290
291 static StatisticsProviderStubImpl* GetInstance() {
292 return Singleton<StatisticsProviderStubImpl,
293 DefaultSingletonTraits<StatisticsProviderStubImpl> >::get();
294 }
295
296 private:
297 friend struct DefaultSingletonTraits<StatisticsProviderStubImpl>;
298
299 StatisticsProviderStubImpl() {
300 }
301
302 DISALLOW_COPY_AND_ASSIGN(StatisticsProviderStubImpl);
303 };
304
305 StatisticsProvider* StatisticsProvider::GetInstance() {
306 if (base::SysInfo::IsRunningOnChromeOS()) {
307 return StatisticsProviderImpl::GetInstance();
308 } else {
309 return StatisticsProviderStubImpl::GetInstance();
310 }
311 }
312
313 } // namespace system
314 } // namespace chromeos
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698