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 |