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

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: Fix browser tests 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
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 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 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "chrome/browser/chromeos/system/statistics_provider.h" 5 #include "chromeos/system/statistics_provider.h"
6 6
7 #include "base/bind.h" 7 #include "base/bind.h"
8 #include "base/command_line.h" 8 #include "base/command_line.h"
9 #include "base/files/file_path.h" 9 #include "base/files/file_path.h"
10 #include "base/location.h"
10 #include "base/logging.h" 11 #include "base/logging.h"
11 #include "base/memory/singleton.h" 12 #include "base/memory/singleton.h"
12 #include "base/path_service.h" 13 #include "base/path_service.h"
14 #include "base/synchronization/cancellation_flag.h"
13 #include "base/synchronization/waitable_event.h" 15 #include "base/synchronization/waitable_event.h"
14 #include "base/sys_info.h" 16 #include "base/sys_info.h"
17 #include "base/task_runner.h"
15 #include "base/threading/thread_restrictions.h" 18 #include "base/threading/thread_restrictions.h"
16 #include "base/time/time.h" 19 #include "base/time/time.h"
17 #include "chromeos/app_mode/kiosk_oem_manifest_parser.h" 20 #include "chromeos/app_mode/kiosk_oem_manifest_parser.h"
18 #include "chromeos/chromeos_constants.h" 21 #include "chromeos/chromeos_constants.h"
19 #include "chromeos/chromeos_switches.h" 22 #include "chromeos/chromeos_switches.h"
20 #include "chromeos/system/name_value_pairs_parser.h" 23 #include "chromeos/system/name_value_pairs_parser.h"
21 #include "content/public/browser/browser_thread.h"
22
23 using content::BrowserThread;
24 24
25 namespace chromeos { 25 namespace chromeos {
26 namespace system { 26 namespace system {
27
27 namespace { 28 namespace {
28 29
29 // Path to the tool used to get system info, and delimiters for the output 30 // Path to the tool used to get system info, and delimiters for the output
30 // format of the tool. 31 // format of the tool.
31 const char* kCrosSystemTool[] = { "/usr/bin/crossystem" }; 32 const char* kCrosSystemTool[] = { "/usr/bin/crossystem" };
32 const char kCrosSystemEq[] = "="; 33 const char kCrosSystemEq[] = "=";
33 const char kCrosSystemDelim[] = "\n"; 34 const char kCrosSystemDelim[] = "\n";
34 const char kCrosSystemCommentDelim[] = "#"; 35 const char kCrosSystemCommentDelim[] = "#";
35 const char kCrosSystemUnknownValue[] = "(error)"; 36 const char kCrosSystemUnknownValue[] = "(error)";
36 37
37 const char kHardwareClassCrosSystemKey[] = "hwid"; 38 const char kHardwareClassCrosSystemKey[] = "hwid";
38 const char kHardwareClassKey[] = "hardware_class";
39 const char kUnknownHardwareClass[] = "unknown"; 39 const char kUnknownHardwareClass[] = "unknown";
40 40
41 // File to get machine hardware info from, and key/value delimiters of 41 // File to get machine hardware info from, and key/value delimiters of
42 // the file. 42 // the file.
43 // /tmp/machine-info is generated by platform/init/chromeos_startup. 43 // /tmp/machine-info is generated by platform/init/chromeos_startup.
44 const char kMachineHardwareInfoFile[] = "/tmp/machine-info"; 44 const char kMachineHardwareInfoFile[] = "/tmp/machine-info";
45 const char kMachineHardwareInfoEq[] = "="; 45 const char kMachineHardwareInfoEq[] = "=";
46 const char kMachineHardwareInfoDelim[] = " \n"; 46 const char kMachineHardwareInfoDelim[] = " \n";
47 47
48 // File to get ECHO coupon info from, and key/value delimiters of 48 // File to get ECHO coupon info from, and key/value delimiters of
(...skipping 11 matching lines...) Expand all
60 const int kTimeoutSecs = 3; 60 const int kTimeoutSecs = 3;
61 61
62 // The location of OEM manifest file used to trigger OOBE flow for kiosk mode. 62 // The location of OEM manifest file used to trigger OOBE flow for kiosk mode.
63 const CommandLine::CharType kOemManifestFilePath[] = 63 const CommandLine::CharType kOemManifestFilePath[] =
64 FILE_PATH_LITERAL("/usr/share/oem/oobe/manifest.json"); 64 FILE_PATH_LITERAL("/usr/share/oem/oobe/manifest.json");
65 65
66 } // namespace 66 } // namespace
67 67
68 // Key values for GetMachineStatistic()/GetMachineFlag() calls. 68 // Key values for GetMachineStatistic()/GetMachineFlag() calls.
69 const char kDevSwitchBootMode[] = "devsw_boot"; 69 const char kDevSwitchBootMode[] = "devsw_boot";
70 const char kHardwareClass[] = "hardware_class"; 70 const char kHardwareClassKey[] = "hardware_class";
71 const char kOffersCouponCodeKey[] = "ubind_attribute"; 71 const char kOffersCouponCodeKey[] = "ubind_attribute";
72 const char kOffersGroupCodeKey[] = "gbind_attribute"; 72 const char kOffersGroupCodeKey[] = "gbind_attribute";
73 const char kOemCanExitEnterpriseEnrollmentKey[] = 73 const char kOemCanExitEnterpriseEnrollmentKey[] = "oem_can_exit_enrollment";
74 "oem_can_exit_enrollment"; 74 const char kOemDeviceRequisitionKey[] = "oem_device_requisition";
75 const char kOemDeviceRequisitionKey[] = 75 const char kOemIsEnterpriseManagedKey[] = "oem_enterprise_managed";
76 "oem_device_requisition"; 76 const char kOemKeyboardDrivenOobeKey[] = "oem_keyboard_driven_oobe";
77 const char kOemIsEnterpriseManagedKey[] =
78 "oem_enterprise_managed";
79 const char kOemKeyboardDrivenOobeKey[] =
80 "oem_keyboard_driven_oobe";
81 77
82 // The StatisticsProvider implementation used in production. 78 // The StatisticsProvider implementation used in production.
83 class StatisticsProviderImpl : public StatisticsProvider { 79 class StatisticsProviderImpl : public StatisticsProvider {
84 public: 80 public:
85 // StatisticsProvider implementation: 81 // StatisticsProvider implementation:
86 virtual void Init() OVERRIDE; 82 virtual void StartLoadingMachineStatistics(
87 virtual void StartLoadingMachineStatistics() OVERRIDE; 83 const scoped_refptr<base::TaskRunner>& file_task_runner,
84 bool load_oem_manifest) OVERRIDE;
88 virtual bool GetMachineStatistic(const std::string& name, 85 virtual bool GetMachineStatistic(const std::string& name,
89 std::string* result) OVERRIDE; 86 std::string* result) OVERRIDE;
90 virtual bool GetMachineFlag(const std::string& name, 87 virtual bool GetMachineFlag(const std::string& name, bool* result) OVERRIDE;
91 bool* result) OVERRIDE; 88 virtual void Shutdown() OVERRIDE;
92 virtual void LoadOemManifest() OVERRIDE;
93 89
94 static StatisticsProviderImpl* GetInstance(); 90 static StatisticsProviderImpl* GetInstance();
95 91
96 protected: 92 protected:
97 StatisticsProviderImpl();
98 void LoadOemManifestFromFile(const base::FilePath& file);
99
100 private:
101 typedef std::map<std::string, bool> MachineFlags; 93 typedef std::map<std::string, bool> MachineFlags;
102 friend struct DefaultSingletonTraits<StatisticsProviderImpl>; 94 friend struct DefaultSingletonTraits<StatisticsProviderImpl>;
103 95
104 // Loads the machine statistcs by examining the system. 96 StatisticsProviderImpl();
105 void LoadMachineStatistics(); 97 virtual ~StatisticsProviderImpl();
106 98
107 bool initialized_; 99 // Waits up to |kTimeoutSecs| for statistics to be loaded. Returns true if
100 // they were loaded successfully.
101 bool WaitForStatisticsLoaded();
102
103 // Loads the machine statistics off of disk. Runs on the file thread.
104 void LoadMachineStatistics(bool load_oem_manifest);
105
106 // Loads the OEM statistics off of disk. Runs on the file thread.
107 void LoadOemManifestFromFile(const base::FilePath& file);
108
108 bool load_statistics_started_; 109 bool load_statistics_started_;
109 NameValuePairsParser::NameValueMap machine_info_; 110 NameValuePairsParser::NameValueMap machine_info_;
110 MachineFlags machine_flags_; 111 MachineFlags machine_flags_;
112 base::CancellationFlag cancellation_flag_;
113 // |on_statistics_loaded_| protects |machine_info_| and |machine_flags_|.
111 base::WaitableEvent on_statistics_loaded_; 114 base::WaitableEvent on_statistics_loaded_;
112 115
116 private:
113 DISALLOW_COPY_AND_ASSIGN(StatisticsProviderImpl); 117 DISALLOW_COPY_AND_ASSIGN(StatisticsProviderImpl);
114 }; 118 };
115 119
116 void StatisticsProviderImpl::Init() { 120 bool StatisticsProviderImpl::WaitForStatisticsLoaded() {
117 DCHECK(!initialized_); 121 CHECK(load_statistics_started_);
118 initialized_ = true; 122 if (on_statistics_loaded_.IsSignaled())
123 return true;
124
125 // Block if the statistics are not loaded yet. Normally this shouldn't
126 // happen excpet during OOBE.
127 base::Time start_time = base::Time::Now();
128 base::ThreadRestrictions::ScopedAllowWait allow_wait;
129 on_statistics_loaded_.TimedWait(base::TimeDelta::FromSeconds(kTimeoutSecs));
130
131 base::TimeDelta dtime = base::Time::Now() - start_time;
satorux1 2013/10/07 05:01:54 nit: dtime -> elapsed?
stevenjb 2013/10/07 18:07:30 We use 'dtime' (delta time) a lot...
132 if (on_statistics_loaded_.IsSignaled()) {
133 LOG(ERROR) << "Statistics loaded after waiting "
134 << dtime.InMilliseconds() << "ms. ";
135 return true;
136 }
137
138 LOG(ERROR) << "Statistics not loaded after waiting "
139 << dtime.InMilliseconds() << "ms. ";
140 return false;
119 } 141 }
120 142
121 bool StatisticsProviderImpl::GetMachineStatistic( 143 bool StatisticsProviderImpl::GetMachineStatistic(
122 const std::string& name, std::string* result) { 144 const std::string& name, std::string* result) {
123 CHECK(initialized_); 145 VLOG(1) << "Machine Statistic requested: " << name;
124 CHECK(load_statistics_started_) 146 if (!WaitForStatisticsLoaded()) {
125 << "GetMachineStatistic called before load started: " << name; 147 LOG(ERROR) << "GetMachineStatistic called before load started: " << name;
satorux1 2013/10/07 05:01:54 maybe don't need this error? WaitForStatisticsLoad
stevenjb 2013/10/07 18:07:30 This error and the one below distinguish between G
126 148 return false;
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 } 149 }
155 150
156 NameValuePairsParser::NameValueMap::iterator iter = machine_info_.find(name); 151 NameValuePairsParser::NameValueMap::iterator iter = machine_info_.find(name);
157 if (iter != machine_info_.end()) { 152 if (iter == machine_info_.end()) {
158 *result = iter->second; 153 if (base::SysInfo::IsRunningOnChromeOS())
159 return true; 154 LOG(WARNING) << "Requested statistic not found: " << name;
155 return false;
160 } 156 }
161 return false; 157 *result = iter->second;
158 return true;
162 } 159 }
163 160
164 bool StatisticsProviderImpl::GetMachineFlag( 161 bool StatisticsProviderImpl::GetMachineFlag(const std::string& name,
165 const std::string& name, bool* result) { 162 bool* result) {
166 MachineFlags::const_iterator iter = machine_flags_.find(name); 163 VLOG(1) << "Machine Flag requested: " << name;
167 if (iter != machine_flags_.end()) { 164 if (!WaitForStatisticsLoaded()) {
168 *result = iter->second; 165 LOG(ERROR) << "GetMachineFlag called before load started: " << name;
satorux1 2013/10/07 05:01:54 ditto.
stevenjb 2013/10/07 18:07:30 See above.
169 return true; 166 return false;
170 } 167 }
171 168
172 return false; 169 MachineFlags::const_iterator iter = machine_flags_.find(name);
170 if (iter == machine_flags_.end()) {
171 if (base::SysInfo::IsRunningOnChromeOS())
172 LOG(WARNING) << "Requested machine flag not found: " << name;
173 return false;
174 }
175 *result = iter->second;
176 return true;
173 } 177 }
174 178
175 void StatisticsProviderImpl::LoadOemManifest() { 179 void StatisticsProviderImpl::Shutdown() {
176 LoadOemManifestFromFile(base::FilePath(kOemManifestFilePath)); 180 cancellation_flag_.Set(); // Cancel any pending loads
177 } 181 }
178 182
179 // manual_reset needs to be true, as we want to keep the signaled state.
180 StatisticsProviderImpl::StatisticsProviderImpl() 183 StatisticsProviderImpl::StatisticsProviderImpl()
181 : initialized_(false), 184 : load_statistics_started_(false),
182 load_statistics_started_(false),
183 on_statistics_loaded_(true /* manual_reset */, 185 on_statistics_loaded_(true /* manual_reset */,
184 false /* initially_signaled */) { 186 false /* initially_signaled */) {
185 } 187 }
186 188
187 void StatisticsProviderImpl::StartLoadingMachineStatistics() { 189 StatisticsProviderImpl::~StatisticsProviderImpl() {
188 DCHECK(initialized_); 190 }
189 DCHECK(!load_statistics_started_); 191
192 void StatisticsProviderImpl::StartLoadingMachineStatistics(
193 const scoped_refptr<base::TaskRunner>& file_task_runner,
194 bool load_oem_manifest) {
195 CHECK(!load_statistics_started_);
190 load_statistics_started_ = true; 196 load_statistics_started_ = true;
191 197
192 VLOG(1) << "Started loading statistics"; 198 VLOG(1) << "Started loading statistics. Load OEM Manifest: "
193 BrowserThread::PostBlockingPoolTask( 199 << load_oem_manifest;
200
201 file_task_runner->PostTask(
194 FROM_HERE, 202 FROM_HERE,
195 base::Bind(&StatisticsProviderImpl::LoadMachineStatistics, 203 base::Bind(&StatisticsProviderImpl::LoadMachineStatistics,
196 base::Unretained(this))); 204 base::Unretained(this),
205 load_oem_manifest));
197 } 206 }
198 207
199 void StatisticsProviderImpl::LoadMachineStatistics() { 208 void StatisticsProviderImpl::LoadMachineStatistics(bool load_oem_manifest) {
satorux1 2013/10/07 05:01:54 add: DCHECK(file_task_runner_.RunsTasksOnCurren
stevenjb 2013/10/07 18:07:30 Done.
stevenjb 2013/10/07 18:43:10 Actually, can't add a DCHECK because we no longer
200 NameValuePairsParser parser(&machine_info_); 209 if (cancellation_flag_.IsSet())
satorux1 2013/10/07 05:01:54 This looks a bit scary. This will be a use-after-f
stevenjb 2013/10/07 18:07:30 I discussed the best way to do this with willchan@
satorux1 2013/10/08 01:47:31 That makes sense. Thank you for adding the comment
210 return;
201 211
202 // Parse all of the key/value pairs from the crossystem tool. 212 if (base::SysInfo::IsRunningOnChromeOS()) {
203 if (!parser.ParseNameValuePairsFromTool( 213 // Parse all of the key/value pairs from the crossystem tool.
204 arraysize(kCrosSystemTool), kCrosSystemTool, kCrosSystemEq, 214 NameValuePairsParser parser(&machine_info_);
205 kCrosSystemDelim, kCrosSystemCommentDelim)) { 215 if (!parser.ParseNameValuePairsFromTool(arraysize(kCrosSystemTool),
206 LOG(WARNING) << "There were errors parsing the output of " 216 kCrosSystemTool,
207 << kCrosSystemTool << "."; 217 kCrosSystemEq,
218 kCrosSystemDelim,
219 kCrosSystemCommentDelim)) {
220 LOG(ERROR) << "Errors parsing output from: " << kCrosSystemTool;
221 }
222
223 parser.GetNameValuePairsFromFile(base::FilePath(kMachineHardwareInfoFile),
224 kMachineHardwareInfoEq,
225 kMachineHardwareInfoDelim);
226 parser.GetNameValuePairsFromFile(base::FilePath(kEchoCouponFile),
227 kEchoCouponEq,
228 kEchoCouponDelim);
229 parser.GetNameValuePairsFromFile(base::FilePath(kVpdFile),
230 kVpdEq,
231 kVpdDelim);
208 } 232 }
209 233
210 // Ensure that the hardware class key is present with the expected 234 // 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". 235 // key name, and if it couldn't be retrieved, that the value is "unknown".
212 std::string hardware_class = machine_info_[kHardwareClassCrosSystemKey]; 236 std::string hardware_class = machine_info_[kHardwareClassCrosSystemKey];
213 if (hardware_class.empty() || hardware_class == kCrosSystemUnknownValue) 237 if (hardware_class.empty() || hardware_class == kCrosSystemUnknownValue)
214 machine_info_[kHardwareClassKey] = kUnknownHardwareClass; 238 machine_info_[kHardwareClassKey] = kUnknownHardwareClass;
215 else 239 else
216 machine_info_[kHardwareClassKey] = hardware_class; 240 machine_info_[kHardwareClassKey] = hardware_class;
217 241
218 parser.GetNameValuePairsFromFile(base::FilePath(kMachineHardwareInfoFile), 242 if (load_oem_manifest) {
219 kMachineHardwareInfoEq, 243 // If kAppOemManifestFile switch is specified, load OEM Manifest file.
220 kMachineHardwareInfoDelim); 244 CommandLine* command_line = CommandLine::ForCurrentProcess();
221 parser.GetNameValuePairsFromFile(base::FilePath(kEchoCouponFile), 245 if (command_line->HasSwitch(switches::kAppOemManifestFile)) {
222 kEchoCouponEq, 246 LoadOemManifestFromFile(
223 kEchoCouponDelim); 247 command_line->GetSwitchValuePath(switches::kAppOemManifestFile));
224 parser.GetNameValuePairsFromFile(base::FilePath(kVpdFile), kVpdEq, kVpdDelim); 248 } else if (base::SysInfo::IsRunningOnChromeOS()) {
249 LoadOemManifestFromFile(base::FilePath(kOemManifestFilePath));
250 }
251 }
225 252
226 // Finished loading the statistics. 253 // Finished loading the statistics.
227 on_statistics_loaded_.Signal(); 254 on_statistics_loaded_.Signal();
228 VLOG(1) << "Finished loading statistics"; 255 VLOG(1) << "Finished loading statistics.";
229 } 256 }
230 257
231 void StatisticsProviderImpl::LoadOemManifestFromFile( 258 void StatisticsProviderImpl::LoadOemManifestFromFile(
232 const base::FilePath& file) { 259 const base::FilePath& file) {
satorux1 2013/10/07 05:01:54 add: DCHECK(file_task_runner_.RunsTasksOnCurrent
stevenjb 2013/10/07 18:07:30 Done.
233 KioskOemManifestParser::Manifest oem_manifest; 260 if (cancellation_flag_.IsSet())
234 if (!KioskOemManifestParser::Load(file, &oem_manifest))
235 return; 261 return;
236 262
263 KioskOemManifestParser::Manifest oem_manifest;
264 if (!KioskOemManifestParser::Load(file, &oem_manifest)) {
265 LOG(WARNING) << "Unable to load OEM Manifest file: " << file.value();
266 return;
267 }
237 machine_info_[kOemDeviceRequisitionKey] = 268 machine_info_[kOemDeviceRequisitionKey] =
238 oem_manifest.device_requisition; 269 oem_manifest.device_requisition;
239 machine_flags_[kOemIsEnterpriseManagedKey] = 270 machine_flags_[kOemIsEnterpriseManagedKey] =
240 oem_manifest.enterprise_managed; 271 oem_manifest.enterprise_managed;
241 machine_flags_[kOemCanExitEnterpriseEnrollmentKey] = 272 machine_flags_[kOemCanExitEnterpriseEnrollmentKey] =
242 oem_manifest.can_exit_enrollment; 273 oem_manifest.can_exit_enrollment;
243 machine_flags_[kOemKeyboardDrivenOobeKey] = 274 machine_flags_[kOemKeyboardDrivenOobeKey] =
244 oem_manifest.keyboard_driven_oobe; 275 oem_manifest.keyboard_driven_oobe;
276
277 VLOG(1) << "Loaded OEM Manifest statistics from " << file.value();
245 } 278 }
246 279
247 StatisticsProviderImpl* StatisticsProviderImpl::GetInstance() { 280 StatisticsProviderImpl* StatisticsProviderImpl::GetInstance() {
248 return Singleton<StatisticsProviderImpl, 281 return Singleton<StatisticsProviderImpl,
249 DefaultSingletonTraits<StatisticsProviderImpl> >::get(); 282 DefaultSingletonTraits<StatisticsProviderImpl> >::get();
250 } 283 }
251 284
252 // The stub StatisticsProvider implementation used on Linux desktop. 285 static StatisticsProvider* g_test_statistics_provider = NULL;
253 class StatisticsProviderStubImpl : public StatisticsProviderImpl {
254 public:
255 // StatisticsProvider implementation:
256 virtual void Init() OVERRIDE {}
257 286
258 virtual void StartLoadingMachineStatistics() OVERRIDE {} 287 // static
288 StatisticsProvider* StatisticsProvider::GetInstance() {
289 if (g_test_statistics_provider)
290 return g_test_statistics_provider;
291 return StatisticsProviderImpl::GetInstance();
292 }
259 293
260 virtual bool GetMachineStatistic(const std::string& name, 294 // static
261 std::string* result) OVERRIDE { 295 void StatisticsProvider::SetTestProvider(StatisticsProvider* test_provider) {
262 if (name == "CHROMEOS_RELEASE_BOARD") { 296 g_test_statistics_provider = test_provider;
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 } 297 }
309 298
310 } // namespace system 299 } // namespace system
311 } // namespace chromeos 300 } // namespace chromeos
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698