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

Side by Side Diff: 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 "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/location.h"
11 #include "base/logging.h"
12 #include "base/path_service.h"
13 #include "base/synchronization/lock.h"
14 #include "base/synchronization/waitable_event.h"
15 #include "base/sys_info.h"
16 #include "base/task_runner.h"
17 #include "base/task_runner_util.h"
18 #include "base/threading/thread_restrictions.h"
19 #include "base/time/time.h"
20 #include "chromeos/app_mode/kiosk_oem_manifest_parser.h"
21 #include "chromeos/chromeos_constants.h"
22 #include "chromeos/chromeos_switches.h"
23 #include "chromeos/system/name_value_pairs_parser.h"
24
25 namespace chromeos {
26 namespace system {
27
28 namespace {
29
30 // Path to the tool used to get system info, and delimiters for the output
31 // format of the tool.
32 const char* kCrosSystemTool[] = { "/usr/bin/crossystem" };
33 const char kCrosSystemEq[] = "=";
34 const char kCrosSystemDelim[] = "\n";
35 const char kCrosSystemCommentDelim[] = "#";
36 const char kCrosSystemUnknownValue[] = "(error)";
37
38 const char kHardwareClassCrosSystemKey[] = "hwid";
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 void LoadMachineStatistics(NameValuePairsParser::NameValueMap* name_value_map) {
67 // Parse all of the key/value pairs from the crossystem tool.
68 NameValuePairsParser parser(name_value_map);
69 if (!parser.ParseNameValuePairsFromTool(arraysize(kCrosSystemTool),
70 kCrosSystemTool,
71 kCrosSystemEq,
72 kCrosSystemDelim,
73 kCrosSystemCommentDelim)) {
74 LOG(WARNING) << "There were errors parsing the output of "
75 << kCrosSystemTool << ".";
76 }
77 parser.GetNameValuePairsFromFile(base::FilePath(kMachineHardwareInfoFile),
78 kMachineHardwareInfoEq,
79 kMachineHardwareInfoDelim);
80 parser.GetNameValuePairsFromFile(
81 base::FilePath(kEchoCouponFile), kEchoCouponEq, kEchoCouponDelim);
82 parser.GetNameValuePairsFromFile(base::FilePath(kVpdFile), kVpdEq, kVpdDelim);
83 }
84
85 } // namespace
86
87 // Key values for GetMachineStatistic()/GetMachineFlag() calls.
88 const char kDevSwitchBootMode[] = "devsw_boot";
89 const char kHardwareClassKey[] = "hardware_class";
90 const char kOffersCouponCodeKey[] = "ubind_attribute";
91 const char kOffersGroupCodeKey[] = "gbind_attribute";
92 const char kOemCanExitEnterpriseEnrollmentKey[] = "oem_can_exit_enrollment";
93 const char kOemDeviceRequisitionKey[] = "oem_device_requisition";
94 const char kOemIsEnterpriseManagedKey[] = "oem_enterprise_managed";
95 const char kOemKeyboardDrivenOobeKey[] = "oem_keyboard_driven_oobe";
96
97 // The StatisticsProvider implementation used in production.
98 class StatisticsProviderImpl : public StatisticsProvider {
99 public:
100 explicit StatisticsProviderImpl(
101 const scoped_refptr<base::TaskRunner>& io_task_runner);
102 virtual ~StatisticsProviderImpl();
103
104 // StatisticsProvider implementation:
105 virtual void StartLoadingMachineStatistics(bool load_oem_manifest) OVERRIDE;
106 virtual bool GetMachineStatistic(const std::string& name,
107 std::string* result) OVERRIDE;
108 virtual bool GetMachineFlag(const std::string& name, bool* result) OVERRIDE;
109
110 // Completes loading of machine statistcs from system files.
111 void MachineStatisticsLoaded(
112 NameValuePairsParser::NameValueMap* name_value_map,
113 bool load_oem_manifest);
114
115 // Completes loading the OEM manifest statistcs.
116 void OemManifestLoaded(KioskOemManifestParser::Manifest* oem_manifest,
117 bool success);
118
119 protected:
120 typedef std::map<std::string, bool> MachineFlags;
121
122 bool load_statistics_started_;
123 base::Lock lock_;
124 scoped_refptr<base::TaskRunner> io_task_runner_;
125 NameValuePairsParser::NameValueMap machine_info_;
126 MachineFlags machine_flags_;
satorux1 2013/10/02 01:36:55 ; // guarded by lock_
stevenjb 2013/10/03 01:17:23 I removed lock_ and made it so that both machine_f
127 base::WaitableEvent on_statistics_loaded_;
128 base::WeakPtrFactory<StatisticsProviderImpl> weak_ptr_factory_;
129
130 private:
131 DISALLOW_COPY_AND_ASSIGN(StatisticsProviderImpl);
132 };
133
134 StatisticsProviderImpl::StatisticsProviderImpl(
135 const scoped_refptr<base::TaskRunner>& io_task_runner)
136 : load_statistics_started_(false),
137 io_task_runner_(io_task_runner),
138 on_statistics_loaded_(true /* manual_reset */,
139 false /* initially_signaled */),
140 weak_ptr_factory_(this) {
141 }
142
143 StatisticsProviderImpl::~StatisticsProviderImpl() {
144 }
145
146 void StatisticsProviderImpl::StartLoadingMachineStatistics(
147 bool load_oem_manifest) {
148 CHECK(!load_statistics_started_);
149 load_statistics_started_ = true;
150
151 VLOG(1) << "Started loading statistics. Load OEM Manifest: "
152 << load_oem_manifest;
153
154 NameValuePairsParser::NameValueMap* name_value_map =
155 new NameValuePairsParser::NameValueMap;
156 io_task_runner_->PostTaskAndReply(
157 FROM_HERE,
158 base::Bind(&LoadMachineStatistics, name_value_map),
159 base::Bind(&StatisticsProviderImpl::MachineStatisticsLoaded,
160 weak_ptr_factory_.GetWeakPtr(),
161 base::Owned(name_value_map),
162 load_oem_manifest));
163 }
164
165 bool StatisticsProviderImpl::GetMachineStatistic(
166 const std::string& name, std::string* result) {
167 // TODO(stevenjb): Thes should be made fatal once fixed. crbug.com/302798.
168 if (!load_statistics_started_) {
169 LOG(ERROR) << "GetMachineStatistic called before load started: " << name;
170 return false;
171 }
172
173 VLOG(1) << "Statistic is requested for " << name;
174 // Block if the statistics are not loaded yet. Normally this shouldn't
175 // happen excpet during OOBE.
176 if (!on_statistics_loaded_.IsSignaled()) {
177 base::Time start_time = base::Time::Now();
178 base::ThreadRestrictions::ScopedAllowWait allow_wait;
179 on_statistics_loaded_.TimedWait(base::TimeDelta::FromSeconds(kTimeoutSecs));
180 base::TimeDelta dtime = base::Time::Now() - start_time;
181 if (!on_statistics_loaded_.IsSignaled()) {
182 LOG(ERROR) << "Statistics weren't loaded after waiting "
183 << dtime.InMilliseconds() << "ms. "
184 << "Requested statistic: " << name;
185 return false;
186 } else {
187 LOG(ERROR) << "Statistic loaded after waiting "
188 << dtime.InMilliseconds() << "ms. "
189 << "Requested statistic: " << name;
190 }
191 }
192
193 NameValuePairsParser::NameValueMap::iterator iter = machine_info_.find(name);
satorux1 2013/10/02 01:36:55 shouldn't we guard machine_info_ with lock_?
stevenjb 2013/10/03 01:17:23 Done.
194 if (iter == machine_info_.end()) {
195 if (base::SysInfo::IsRunningOnChromeOS())
196 LOG(ERROR) << "Requested statistic not found: " << name;
197 return false;
198 }
199
200 *result = iter->second;
201 return true;
202 }
203
204 bool StatisticsProviderImpl::GetMachineFlag(const std::string& name,
205 bool* result) {
206 base::AutoLock lock(lock_);
207 MachineFlags::const_iterator iter = machine_flags_.find(name);
208 if (iter == machine_flags_.end()) {
209 if (base::SysInfo::IsRunningOnChromeOS())
210 LOG(ERROR) << "Requested machine flag not found: " << name;
211 return false;
212 }
213 *result = iter->second;
214 return true;
215 }
216
217 void StatisticsProviderImpl::MachineStatisticsLoaded(
218 NameValuePairsParser::NameValueMap* name_value_map,
219 bool load_oem_manifest) {
220 base::AutoLock lock(lock_);
221
222 machine_info_.swap(*name_value_map);
223 // Ensure that the hardware class key is present with the expected
224 // key name, and if it couldn't be retrieved, that the value is "unknown".
225 std::string hardware_class = machine_info_[kHardwareClassCrosSystemKey];
226 if (hardware_class.empty() || hardware_class == kCrosSystemUnknownValue)
227 machine_info_[kHardwareClassKey] = kUnknownHardwareClass;
228 else
229 machine_info_[kHardwareClassKey] = hardware_class;
230
231 if (load_oem_manifest) {
232 VLOG(1) << "Started loading OEM Manifest";
233 KioskOemManifestParser::Manifest* oem_manifest =
234 new KioskOemManifestParser::Manifest;
235 base::PostTaskAndReplyWithResult(
236 io_task_runner_.get(),
237 FROM_HERE,
238 base::Bind(&KioskOemManifestParser::Load,
239 base::FilePath(kOemManifestFilePath),
240 oem_manifest),
241 base::Bind(&StatisticsProviderImpl::OemManifestLoaded,
242 weak_ptr_factory_.GetWeakPtr(),
243 base::Owned(oem_manifest)));
244 return;
245 }
246 // Finished loading the statistics.
247 on_statistics_loaded_.Signal();
248 VLOG(1) << "Finished loading statistics";
249 }
250
251 void StatisticsProviderImpl::OemManifestLoaded(
252 KioskOemManifestParser::Manifest* oem_manifest,
253 bool success) {
254 if (success) {
255 machine_info_[kOemDeviceRequisitionKey] = oem_manifest->device_requisition;
256 machine_flags_[kOemIsEnterpriseManagedKey] =
257 oem_manifest->enterprise_managed;
258 machine_flags_[kOemCanExitEnterpriseEnrollmentKey] =
259 oem_manifest->can_exit_enrollment;
260 machine_flags_[kOemKeyboardDrivenOobeKey] =
261 oem_manifest->keyboard_driven_oobe;
262 }
263 // Finished loading the statistics.
264 on_statistics_loaded_.Signal();
265 VLOG(1) << "Finished loading statistics and OEM Manifest";
266 }
267
268 // The stub StatisticsProvider implementation used on Linux desktop.
269 class StatisticsProviderStubImpl : public StatisticsProviderImpl {
270 public:
271 explicit StatisticsProviderStubImpl(
272 const scoped_refptr<base::TaskRunner>& io_task_runner)
273 : StatisticsProviderImpl(io_task_runner) {}
274 virtual ~StatisticsProviderStubImpl() {}
275
276 // StatisticsProvider implementation:
277 virtual void StartLoadingMachineStatistics(bool load_oem_manifest) OVERRIDE {
278 load_statistics_started_ = true;
279 if (!load_oem_manifest) {
280 on_statistics_loaded_.Signal();
281 return;
282 }
283
284 // If kAppOemManifestFile switch is specified, load OEM Manifest file.
285 CommandLine* command_line = CommandLine::ForCurrentProcess();
286 if (!command_line->HasSwitch(switches::kAppOemManifestFile)) {
287 on_statistics_loaded_.Signal();
288 return;
289 }
290 KioskOemManifestParser::Manifest* oem_manifest =
291 new KioskOemManifestParser::Manifest;
292 base::FilePath file_path =
293 command_line->GetSwitchValuePath(switches::kAppOemManifestFile);
294 base::PostTaskAndReplyWithResult(
295 io_task_runner_.get(),
296 FROM_HERE,
297 base::Bind(&KioskOemManifestParser::Load,
298 base::FilePath(kOemManifestFilePath),
299 oem_manifest),
300 base::Bind(&StatisticsProviderImpl::OemManifestLoaded,
301 weak_ptr_factory_.GetWeakPtr(),
302 base::Owned(oem_manifest)));
303 }
304
305 private:
306 DISALLOW_COPY_AND_ASSIGN(StatisticsProviderStubImpl);
307 };
308
309 static StatisticsProvider* g_statistics_provider = NULL;
310
311 // static
312 void StatisticsProvider::Initialize(
313 const scoped_refptr<base::TaskRunner>& io_task_runner) {
314 CHECK(!g_statistics_provider);
315 if (base::SysInfo::IsRunningOnChromeOS()) {
316 g_statistics_provider = new StatisticsProviderImpl(io_task_runner);
317 } else {
318 g_statistics_provider = new StatisticsProviderStubImpl(io_task_runner);
319 }
320 }
321
322 // static
323 void StatisticsProvider::Shutdown() {
324 delete g_statistics_provider;
325 g_statistics_provider = NULL;
326 }
327
328 StatisticsProvider* StatisticsProvider::GetInstance() {
329 CHECK(g_statistics_provider);
330 return g_statistics_provider;
331 }
332
333 } // namespace system
334 } // namespace chromeos
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698