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

Unified 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, 3 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 side-by-side diff with in-line comments
Download patch
Index: chromeos/system/statistics_provider.cc
diff --git a/chromeos/system/statistics_provider.cc b/chromeos/system/statistics_provider.cc
new file mode 100644
index 0000000000000000000000000000000000000000..ebd10777474f34c4c0e8e2cd7b881394458b02ab
--- /dev/null
+++ b/chromeos/system/statistics_provider.cc
@@ -0,0 +1,334 @@
+// Copyright (c) 2012 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "chromeos/system/statistics_provider.h"
+
+#include "base/bind.h"
+#include "base/command_line.h"
+#include "base/files/file_path.h"
+#include "base/location.h"
+#include "base/logging.h"
+#include "base/path_service.h"
+#include "base/synchronization/lock.h"
+#include "base/synchronization/waitable_event.h"
+#include "base/sys_info.h"
+#include "base/task_runner.h"
+#include "base/task_runner_util.h"
+#include "base/threading/thread_restrictions.h"
+#include "base/time/time.h"
+#include "chromeos/app_mode/kiosk_oem_manifest_parser.h"
+#include "chromeos/chromeos_constants.h"
+#include "chromeos/chromeos_switches.h"
+#include "chromeos/system/name_value_pairs_parser.h"
+
+namespace chromeos {
+namespace system {
+
+namespace {
+
+// Path to the tool used to get system info, and delimiters for the output
+// format of the tool.
+const char* kCrosSystemTool[] = { "/usr/bin/crossystem" };
+const char kCrosSystemEq[] = "=";
+const char kCrosSystemDelim[] = "\n";
+const char kCrosSystemCommentDelim[] = "#";
+const char kCrosSystemUnknownValue[] = "(error)";
+
+const char kHardwareClassCrosSystemKey[] = "hwid";
+const char kUnknownHardwareClass[] = "unknown";
+
+// File to get machine hardware info from, and key/value delimiters of
+// the file.
+// /tmp/machine-info is generated by platform/init/chromeos_startup.
+const char kMachineHardwareInfoFile[] = "/tmp/machine-info";
+const char kMachineHardwareInfoEq[] = "=";
+const char kMachineHardwareInfoDelim[] = " \n";
+
+// File to get ECHO coupon info from, and key/value delimiters of
+// the file.
+const char kEchoCouponFile[] = "/var/cache/echo/vpd_echo.txt";
+const char kEchoCouponEq[] = "=";
+const char kEchoCouponDelim[] = "\n";
+
+// File to get VPD info from, and key/value delimiters of the file.
+const char kVpdFile[] = "/var/log/vpd_2.0.txt";
+const char kVpdEq[] = "=";
+const char kVpdDelim[] = "\n";
+
+// Timeout that we should wait for statistics to get loaded
+const int kTimeoutSecs = 3;
+
+// The location of OEM manifest file used to trigger OOBE flow for kiosk mode.
+const CommandLine::CharType kOemManifestFilePath[] =
+ FILE_PATH_LITERAL("/usr/share/oem/oobe/manifest.json");
+
+void LoadMachineStatistics(NameValuePairsParser::NameValueMap* name_value_map) {
+ // Parse all of the key/value pairs from the crossystem tool.
+ NameValuePairsParser parser(name_value_map);
+ if (!parser.ParseNameValuePairsFromTool(arraysize(kCrosSystemTool),
+ kCrosSystemTool,
+ kCrosSystemEq,
+ kCrosSystemDelim,
+ kCrosSystemCommentDelim)) {
+ LOG(WARNING) << "There were errors parsing the output of "
+ << kCrosSystemTool << ".";
+ }
+ parser.GetNameValuePairsFromFile(base::FilePath(kMachineHardwareInfoFile),
+ kMachineHardwareInfoEq,
+ kMachineHardwareInfoDelim);
+ parser.GetNameValuePairsFromFile(
+ base::FilePath(kEchoCouponFile), kEchoCouponEq, kEchoCouponDelim);
+ parser.GetNameValuePairsFromFile(base::FilePath(kVpdFile), kVpdEq, kVpdDelim);
+}
+
+} // namespace
+
+// Key values for GetMachineStatistic()/GetMachineFlag() calls.
+const char kDevSwitchBootMode[] = "devsw_boot";
+const char kHardwareClassKey[] = "hardware_class";
+const char kOffersCouponCodeKey[] = "ubind_attribute";
+const char kOffersGroupCodeKey[] = "gbind_attribute";
+const char kOemCanExitEnterpriseEnrollmentKey[] = "oem_can_exit_enrollment";
+const char kOemDeviceRequisitionKey[] = "oem_device_requisition";
+const char kOemIsEnterpriseManagedKey[] = "oem_enterprise_managed";
+const char kOemKeyboardDrivenOobeKey[] = "oem_keyboard_driven_oobe";
+
+// The StatisticsProvider implementation used in production.
+class StatisticsProviderImpl : public StatisticsProvider {
+ public:
+ explicit StatisticsProviderImpl(
+ const scoped_refptr<base::TaskRunner>& io_task_runner);
+ virtual ~StatisticsProviderImpl();
+
+ // StatisticsProvider implementation:
+ virtual void StartLoadingMachineStatistics(bool load_oem_manifest) OVERRIDE;
+ virtual bool GetMachineStatistic(const std::string& name,
+ std::string* result) OVERRIDE;
+ virtual bool GetMachineFlag(const std::string& name, bool* result) OVERRIDE;
+
+ // Completes loading of machine statistcs from system files.
+ void MachineStatisticsLoaded(
+ NameValuePairsParser::NameValueMap* name_value_map,
+ bool load_oem_manifest);
+
+ // Completes loading the OEM manifest statistcs.
+ void OemManifestLoaded(KioskOemManifestParser::Manifest* oem_manifest,
+ bool success);
+
+ protected:
+ typedef std::map<std::string, bool> MachineFlags;
+
+ bool load_statistics_started_;
+ base::Lock lock_;
+ scoped_refptr<base::TaskRunner> io_task_runner_;
+ NameValuePairsParser::NameValueMap machine_info_;
+ 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
+ base::WaitableEvent on_statistics_loaded_;
+ base::WeakPtrFactory<StatisticsProviderImpl> weak_ptr_factory_;
+
+ private:
+ DISALLOW_COPY_AND_ASSIGN(StatisticsProviderImpl);
+};
+
+StatisticsProviderImpl::StatisticsProviderImpl(
+ const scoped_refptr<base::TaskRunner>& io_task_runner)
+ : load_statistics_started_(false),
+ io_task_runner_(io_task_runner),
+ on_statistics_loaded_(true /* manual_reset */,
+ false /* initially_signaled */),
+ weak_ptr_factory_(this) {
+}
+
+StatisticsProviderImpl::~StatisticsProviderImpl() {
+}
+
+void StatisticsProviderImpl::StartLoadingMachineStatistics(
+ bool load_oem_manifest) {
+ CHECK(!load_statistics_started_);
+ load_statistics_started_ = true;
+
+ VLOG(1) << "Started loading statistics. Load OEM Manifest: "
+ << load_oem_manifest;
+
+ NameValuePairsParser::NameValueMap* name_value_map =
+ new NameValuePairsParser::NameValueMap;
+ io_task_runner_->PostTaskAndReply(
+ FROM_HERE,
+ base::Bind(&LoadMachineStatistics, name_value_map),
+ base::Bind(&StatisticsProviderImpl::MachineStatisticsLoaded,
+ weak_ptr_factory_.GetWeakPtr(),
+ base::Owned(name_value_map),
+ load_oem_manifest));
+}
+
+bool StatisticsProviderImpl::GetMachineStatistic(
+ const std::string& name, std::string* result) {
+ // TODO(stevenjb): Thes should be made fatal once fixed. crbug.com/302798.
+ if (!load_statistics_started_) {
+ LOG(ERROR) << "GetMachineStatistic called before load started: " << name;
+ return false;
+ }
+
+ VLOG(1) << "Statistic is requested for " << name;
+ // Block if the statistics are not loaded yet. Normally this shouldn't
+ // happen excpet during OOBE.
+ if (!on_statistics_loaded_.IsSignaled()) {
+ base::Time start_time = base::Time::Now();
+ base::ThreadRestrictions::ScopedAllowWait allow_wait;
+ on_statistics_loaded_.TimedWait(base::TimeDelta::FromSeconds(kTimeoutSecs));
+ base::TimeDelta dtime = base::Time::Now() - start_time;
+ if (!on_statistics_loaded_.IsSignaled()) {
+ LOG(ERROR) << "Statistics weren't loaded after waiting "
+ << dtime.InMilliseconds() << "ms. "
+ << "Requested statistic: " << name;
+ return false;
+ } else {
+ LOG(ERROR) << "Statistic loaded after waiting "
+ << dtime.InMilliseconds() << "ms. "
+ << "Requested statistic: " << name;
+ }
+ }
+
+ 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.
+ if (iter == machine_info_.end()) {
+ if (base::SysInfo::IsRunningOnChromeOS())
+ LOG(ERROR) << "Requested statistic not found: " << name;
+ return false;
+ }
+
+ *result = iter->second;
+ return true;
+}
+
+bool StatisticsProviderImpl::GetMachineFlag(const std::string& name,
+ bool* result) {
+ base::AutoLock lock(lock_);
+ MachineFlags::const_iterator iter = machine_flags_.find(name);
+ if (iter == machine_flags_.end()) {
+ if (base::SysInfo::IsRunningOnChromeOS())
+ LOG(ERROR) << "Requested machine flag not found: " << name;
+ return false;
+ }
+ *result = iter->second;
+ return true;
+}
+
+void StatisticsProviderImpl::MachineStatisticsLoaded(
+ NameValuePairsParser::NameValueMap* name_value_map,
+ bool load_oem_manifest) {
+ base::AutoLock lock(lock_);
+
+ machine_info_.swap(*name_value_map);
+ // Ensure that the hardware class key is present with the expected
+ // key name, and if it couldn't be retrieved, that the value is "unknown".
+ std::string hardware_class = machine_info_[kHardwareClassCrosSystemKey];
+ if (hardware_class.empty() || hardware_class == kCrosSystemUnknownValue)
+ machine_info_[kHardwareClassKey] = kUnknownHardwareClass;
+ else
+ machine_info_[kHardwareClassKey] = hardware_class;
+
+ if (load_oem_manifest) {
+ VLOG(1) << "Started loading OEM Manifest";
+ KioskOemManifestParser::Manifest* oem_manifest =
+ new KioskOemManifestParser::Manifest;
+ base::PostTaskAndReplyWithResult(
+ io_task_runner_.get(),
+ FROM_HERE,
+ base::Bind(&KioskOemManifestParser::Load,
+ base::FilePath(kOemManifestFilePath),
+ oem_manifest),
+ base::Bind(&StatisticsProviderImpl::OemManifestLoaded,
+ weak_ptr_factory_.GetWeakPtr(),
+ base::Owned(oem_manifest)));
+ return;
+ }
+ // Finished loading the statistics.
+ on_statistics_loaded_.Signal();
+ VLOG(1) << "Finished loading statistics";
+}
+
+void StatisticsProviderImpl::OemManifestLoaded(
+ KioskOemManifestParser::Manifest* oem_manifest,
+ bool success) {
+ if (success) {
+ machine_info_[kOemDeviceRequisitionKey] = oem_manifest->device_requisition;
+ machine_flags_[kOemIsEnterpriseManagedKey] =
+ oem_manifest->enterprise_managed;
+ machine_flags_[kOemCanExitEnterpriseEnrollmentKey] =
+ oem_manifest->can_exit_enrollment;
+ machine_flags_[kOemKeyboardDrivenOobeKey] =
+ oem_manifest->keyboard_driven_oobe;
+ }
+ // Finished loading the statistics.
+ on_statistics_loaded_.Signal();
+ VLOG(1) << "Finished loading statistics and OEM Manifest";
+}
+
+// The stub StatisticsProvider implementation used on Linux desktop.
+class StatisticsProviderStubImpl : public StatisticsProviderImpl {
+ public:
+ explicit StatisticsProviderStubImpl(
+ const scoped_refptr<base::TaskRunner>& io_task_runner)
+ : StatisticsProviderImpl(io_task_runner) {}
+ virtual ~StatisticsProviderStubImpl() {}
+
+ // StatisticsProvider implementation:
+ virtual void StartLoadingMachineStatistics(bool load_oem_manifest) OVERRIDE {
+ load_statistics_started_ = true;
+ if (!load_oem_manifest) {
+ on_statistics_loaded_.Signal();
+ return;
+ }
+
+ // If kAppOemManifestFile switch is specified, load OEM Manifest file.
+ CommandLine* command_line = CommandLine::ForCurrentProcess();
+ if (!command_line->HasSwitch(switches::kAppOemManifestFile)) {
+ on_statistics_loaded_.Signal();
+ return;
+ }
+ KioskOemManifestParser::Manifest* oem_manifest =
+ new KioskOemManifestParser::Manifest;
+ base::FilePath file_path =
+ command_line->GetSwitchValuePath(switches::kAppOemManifestFile);
+ base::PostTaskAndReplyWithResult(
+ io_task_runner_.get(),
+ FROM_HERE,
+ base::Bind(&KioskOemManifestParser::Load,
+ base::FilePath(kOemManifestFilePath),
+ oem_manifest),
+ base::Bind(&StatisticsProviderImpl::OemManifestLoaded,
+ weak_ptr_factory_.GetWeakPtr(),
+ base::Owned(oem_manifest)));
+ }
+
+ private:
+ DISALLOW_COPY_AND_ASSIGN(StatisticsProviderStubImpl);
+};
+
+static StatisticsProvider* g_statistics_provider = NULL;
+
+// static
+void StatisticsProvider::Initialize(
+ const scoped_refptr<base::TaskRunner>& io_task_runner) {
+ CHECK(!g_statistics_provider);
+ if (base::SysInfo::IsRunningOnChromeOS()) {
+ g_statistics_provider = new StatisticsProviderImpl(io_task_runner);
+ } else {
+ g_statistics_provider = new StatisticsProviderStubImpl(io_task_runner);
+ }
+}
+
+// static
+void StatisticsProvider::Shutdown() {
+ delete g_statistics_provider;
+ g_statistics_provider = NULL;
+}
+
+StatisticsProvider* StatisticsProvider::GetInstance() {
+ CHECK(g_statistics_provider);
+ return g_statistics_provider;
+}
+
+} // namespace system
+} // namespace chromeos

Powered by Google App Engine
This is Rietveld 408576698