| OLD | NEW |
| 1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2011 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 "extension_info_private_api_chromeos.h" | 5 #include "extension_info_private_api_chromeos.h" |
| 6 | 6 |
| 7 #include <map> | |
| 8 #include "base/threading/non_thread_safe.h" | |
| 9 #include "base/lazy_instance.h" | |
| 10 #include "base/logging.h" | |
| 11 #include "base/values.h" | 7 #include "base/values.h" |
| 12 #include "chrome/browser/chromeos/cros/cros_library.h" | 8 #include "chrome/browser/chromeos/cros/cros_library.h" |
| 13 #include "chrome/browser/chromeos/cros/network_library.h" | 9 #include "chrome/browser/chromeos/cros/network_library.h" |
| 14 #include "chrome/browser/chromeos/customization_document.h" | 10 #include "chrome/browser/chromeos/system_access.h" |
| 15 #include "chrome/common/extensions/extension_error_utils.h" | |
| 16 #include "content/browser/browser_thread.h" | |
| 17 | 11 |
| 18 using chromeos::CrosLibrary; | 12 using chromeos::CrosLibrary; |
| 19 using chromeos::NetworkLibrary; | 13 using chromeos::NetworkLibrary; |
| 20 | 14 |
| 21 namespace { | 15 namespace { |
| 22 | 16 |
| 23 // Key which corresponds to the HWID setting. | 17 // Key which corresponds to the HWID setting. |
| 24 const char kPropertyHWID[] = "hwid"; | 18 const char kPropertyHWID[] = "hwid"; |
| 25 | 19 |
| 26 // Key which corresponds to the home provider property. | 20 // Key which corresponds to the home provider property. |
| 27 const char kPropertyHomeProvider[] = "homeProvider"; | 21 const char kPropertyHomeProvider[] = "homeProvider"; |
| 28 | 22 |
| 29 // Path to OEM partner startup customization manifest. | 23 } // namespace |
| 30 const char kStartupCustomizationManifestPath[] = | |
| 31 "/opt/oem/etc/startup_manifest.json"; | |
| 32 | 24 |
| 33 // Keeps cached values to avoid unnecessary file operations. Should only be | 25 GetChromeosInfoFunction::GetChromeosInfoFunction() { |
| 34 // used from the UI thread. | |
| 35 class CachedProperties : base::NonThreadSafe { | |
| 36 public: | |
| 37 ~CachedProperties(); | |
| 38 // Gets value for the property with the given name. Return whether value has | |
| 39 // been found. | |
| 40 bool GetValue(const std::string& property_name, std::string* value); | |
| 41 | |
| 42 // Updates cached properties with the given item. | |
| 43 void Update(const std::pair<std::string, std::string>& item); | |
| 44 | |
| 45 private: | |
| 46 typedef std::map<std::string, std::string> PropertyMap; | |
| 47 PropertyMap cache_; | |
| 48 }; | |
| 49 | |
| 50 CachedProperties::~CachedProperties() { | |
| 51 // It is safe to delete this class on any thread since class is used | |
| 52 // through LazyInstance. | |
| 53 DetachFromThread(); | |
| 54 } | 26 } |
| 55 | 27 |
| 56 bool CachedProperties::GetValue(const std::string& property_name, | 28 GetChromeosInfoFunction::~GetChromeosInfoFunction() { |
| 57 std::string* value) { | |
| 58 DCHECK(CalledOnValidThread()); | |
| 59 PropertyMap::iterator iter = cache_.find(property_name); | |
| 60 if (iter != cache_.end()) { | |
| 61 (*value) = iter->second; | |
| 62 return true; | |
| 63 } | |
| 64 return false; | |
| 65 } | 29 } |
| 66 | 30 |
| 67 // Updates cached properties with the given value of the property. | 31 bool GetChromeosInfoFunction::RunImpl() { |
| 68 void CachedProperties::Update( | 32 ListValue* list = NULL; |
| 69 const std::pair<std::string, std::string>& item) { | 33 EXTENSION_FUNCTION_VALIDATE(args_->GetList(0, &list)); |
| 70 DCHECK(CalledOnValidThread()); | 34 scoped_ptr<DictionaryValue> result(new DictionaryValue()); |
| 71 cache_.insert(item); | 35 for (size_t i = 0; i < list->GetSize(); ++i) { |
| 36 std::string property_name; |
| 37 EXTENSION_FUNCTION_VALIDATE(list->GetString(i, &property_name)); |
| 38 std::string value; |
| 39 if (GetValue(property_name, &value)) |
| 40 result->Set(property_name, Value::CreateStringValue(value)); |
| 41 } |
| 42 result_.reset(result.release()); |
| 43 SendResponse(true); |
| 44 return true; |
| 72 } | 45 } |
| 73 | 46 |
| 74 // Provides customization properties. Should be used only on the FILE thread. | 47 bool GetChromeosInfoFunction::GetValue(const std::string& property_name, |
| 75 class CustomizationData : base::NonThreadSafe { | 48 std::string* value) { |
| 76 public: | 49 value->clear(); |
| 77 CustomizationData(); | |
| 78 ~CustomizationData(); | |
| 79 | |
| 80 // Gets value for the property with the given name. Return whether value has | |
| 81 // been found. | |
| 82 bool GetValue(const std::string& property_name, std::string* value); | |
| 83 | |
| 84 private: | |
| 85 // Keeps customization document from which properties are extracted. | |
| 86 chromeos::StartupCustomizationDocument document_; | |
| 87 | |
| 88 DISALLOW_COPY_AND_ASSIGN(CustomizationData); | |
| 89 }; | |
| 90 | |
| 91 CustomizationData::CustomizationData() { | |
| 92 DCHECK(CalledOnValidThread()); | |
| 93 document_.LoadManifestFromFile(FilePath(kStartupCustomizationManifestPath)); | |
| 94 } | |
| 95 | |
| 96 CustomizationData::~CustomizationData() { | |
| 97 // It is safe to delete this class on any thread since class is used | |
| 98 // through LazyInstance. | |
| 99 DetachFromThread(); | |
| 100 } | |
| 101 | |
| 102 bool CustomizationData::GetValue(const std::string& property_name, | |
| 103 std::string* value) { | |
| 104 DCHECK(CalledOnValidThread()); | |
| 105 if (property_name == kPropertyHWID) { | 50 if (property_name == kPropertyHWID) { |
| 106 (*value) = document_.GetHWID(); | 51 chromeos::SystemAccess* system = chromeos::SystemAccess::GetInstance(); |
| 52 system->GetMachineStatistic(kPropertyHWID, value); |
| 107 } else if (property_name == kPropertyHomeProvider) { | 53 } else if (property_name == kPropertyHomeProvider) { |
| 108 (*value) = ""; | |
| 109 if (CrosLibrary::Get()->EnsureLoaded()) { | 54 if (CrosLibrary::Get()->EnsureLoaded()) { |
| 110 NetworkLibrary* netlib = CrosLibrary::Get()->GetNetworkLibrary(); | 55 NetworkLibrary* netlib = CrosLibrary::Get()->GetNetworkLibrary(); |
| 111 const chromeos::NetworkDevice* device = netlib->FindCellularDevice(); | 56 const chromeos::NetworkDevice* device = netlib->FindCellularDevice(); |
| 112 if (device) { | 57 if (device) { |
| 113 DLOG(INFO) << "Taking the home provider of " << device->name() | 58 DLOG(INFO) << "Taking the home provider of " << device->name() |
| 114 << " (" << device->device_path() << ")"; | 59 << " (" << device->device_path() << ")"; |
| 115 (*value) = device->home_provider(); | 60 (*value) = device->home_provider(); |
| 116 } else { | 61 } else { |
| 117 LOG(WARNING) << "Can't find cellular device."; | 62 LOG(WARNING) << "Can't find cellular device."; |
| 118 } | 63 } |
| 119 } else { | 64 } else { |
| 120 LOG(ERROR) << "CrosLibrary can't be loaded."; | 65 LOG(ERROR) << "CrosLibrary can't be loaded."; |
| 121 } | 66 } |
| 122 } else { | 67 } else { |
| 123 LOG(ERROR) << "Unknown property request: " << property_name; | 68 LOG(ERROR) << "Unknown property request: " << property_name; |
| 124 return false; | 69 return false; |
| 125 } | 70 } |
| 126 return true; | 71 return true; |
| 127 } | 72 } |
| 128 | |
| 129 // Shared instances. | |
| 130 base::LazyInstance<CachedProperties> g_cached_properties( | |
| 131 base::LINKER_INITIALIZED); | |
| 132 base::LazyInstance<CustomizationData> g_customization(base::LINKER_INITIALIZED); | |
| 133 | |
| 134 } // namespace | |
| 135 | |
| 136 GetChromeosInfoFunction::GetChromeosInfoFunction() | |
| 137 : result_dictionary_(new DictionaryValue) { | |
| 138 } | |
| 139 | |
| 140 GetChromeosInfoFunction::~GetChromeosInfoFunction() { | |
| 141 } | |
| 142 | |
| 143 bool GetChromeosInfoFunction::RunImpl() { | |
| 144 ListValue* list = NULL; | |
| 145 EXTENSION_FUNCTION_VALIDATE(args_->GetList(0, &list)); | |
| 146 for (size_t i = 0; i < list->GetSize(); ++i) { | |
| 147 std::string property_name; | |
| 148 EXTENSION_FUNCTION_VALIDATE(list->GetString(i, &property_name)); | |
| 149 std::string value; | |
| 150 if (g_cached_properties.Get().GetValue(property_name, &value)) { | |
| 151 result_dictionary_->Set(property_name, Value::CreateStringValue(value)); | |
| 152 } else { | |
| 153 properties_.push_back(property_name); | |
| 154 } | |
| 155 } | |
| 156 | |
| 157 if (!properties_.empty()) { | |
| 158 // This will calls us back on UI thread. | |
| 159 BrowserThread::PostTask( | |
| 160 BrowserThread::FILE, | |
| 161 FROM_HERE, | |
| 162 NewRunnableMethod(this, | |
| 163 &GetChromeosInfoFunction::LoadValues)); | |
| 164 } else { | |
| 165 // Early answer is ready. | |
| 166 result_.reset(result_dictionary_.release()); | |
| 167 SendResponse(true); | |
| 168 } | |
| 169 return true; | |
| 170 } | |
| 171 | |
| 172 void GetChromeosInfoFunction::RespondOnUIThread() { | |
| 173 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | |
| 174 for (size_t i = 0; i < new_results_.size(); ++i) { | |
| 175 result_dictionary_->Set(new_results_[i].first, | |
| 176 Value::CreateStringValue(new_results_[i].second)); | |
| 177 g_cached_properties.Get().Update(new_results_[i]); | |
| 178 } | |
| 179 result_.reset(result_dictionary_.release()); | |
| 180 SendResponse(true); | |
| 181 } | |
| 182 | |
| 183 void GetChromeosInfoFunction::LoadValues() { | |
| 184 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE)); | |
| 185 new_results_.clear(); | |
| 186 for (size_t i = 0; i < properties_.size(); ++i) { | |
| 187 std::string value; | |
| 188 if (g_customization.Get().GetValue(properties_[i], &value)) | |
| 189 new_results_.push_back(std::make_pair(properties_[i], value)); | |
| 190 } | |
| 191 BrowserThread::PostTask( | |
| 192 BrowserThread::UI, | |
| 193 FROM_HERE, | |
| 194 NewRunnableMethod( | |
| 195 this, | |
| 196 &GetChromeosInfoFunction::RespondOnUIThread)); | |
| 197 } | |
| OLD | NEW |