1 // Copyright 2012 The ChromiumOS Authors
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 "include/prop_registry.h"
6
7 #include <set>
8 #include <string>
9
10 #include <json/value.h>
11
12 #include "include/activity_log.h"
13 #include "include/gestures.h"
14
15 using std::set;
16 using std::string;
17
18 namespace gestures {
19
Register(Property * prop)20 void PropRegistry::Register(Property* prop) {
21 props_.insert(prop);
22 if (prop_provider_)
23 prop->CreateProp();
24 }
25
Unregister(Property * prop)26 void PropRegistry::Unregister(Property* prop) {
27 if (props_.erase(prop) != 1)
28 Err("Unregister failed?");
29 if (prop_provider_)
30 prop->DestroyProp();
31 }
32
SetPropProvider(GesturesPropProvider * prop_provider,void * data)33 void PropRegistry::SetPropProvider(GesturesPropProvider* prop_provider,
34 void* data) {
35 if (prop_provider_ == prop_provider)
36 return;
37 if (prop_provider_) {
38 for (std::set<Property*>::iterator it = props_.begin(), e= props_.end();
39 it != e; ++it)
40 (*it)->DestroyProp();
41 }
42 prop_provider_ = prop_provider;
43 prop_provider_data_ = data;
44 if (prop_provider_)
45 for (std::set<Property*>::iterator it = props_.begin(), e= props_.end();
46 it != e; ++it)
47 (*it)->CreateProp();
48 }
49
CreateProp()50 void Property::CreateProp() {
51 if (gprop_)
52 Err("Property already created");
53 CreatePropImpl();
54 if (parent_) {
55 parent_->PropProvider()->register_handlers_fn(
56 parent_->PropProviderData(),
57 gprop_,
58 this,
59 &StaticHandleGesturesPropWillRead,
60 &StaticHandleGesturesPropWritten);
61 }
62 }
63
DestroyProp()64 void Property::DestroyProp() {
65 if (!gprop_) {
66 Err("gprop_ already freed!");
67 return;
68 }
69 parent_->PropProvider()->free_fn(parent_->PropProviderData(), gprop_);
70 gprop_ = NULL;
71 }
72
CreatePropImpl()73 void BoolProperty::CreatePropImpl() {
74 GesturesPropBool orig_val = val_;
75 gprop_ = parent_->PropProvider()->create_bool_fn(
76 parent_->PropProviderData(),
77 name(),
78 &val_,
79 1,
80 &val_);
81 if (delegate_ && orig_val != val_)
82 delegate_->BoolWasWritten(this);
83 }
84
NewValue() const85 Json::Value BoolProperty::NewValue() const {
86 return Json::Value(val_ != 0);
87 }
88
SetValue(const Json::Value & value)89 bool BoolProperty::SetValue(const Json::Value& value) {
90 if (value.type() != Json::booleanValue) {
91 return false;
92 }
93 val_ = value.asBool();
94 return true;
95 }
96
HandleGesturesPropWritten()97 void BoolProperty::HandleGesturesPropWritten() {
98 if (parent_ && parent_->activity_log()) {
99 ActivityLog::PropChangeEntry entry = {
100 name(), ActivityLog::PropChangeEntry::kBoolProp, { 0 }
101 };
102 entry.value.bool_val = val_;
103 parent_->activity_log()->LogPropChange(entry);
104 }
105 if (delegate_)
106 delegate_->BoolWasWritten(this);
107 }
108
CreatePropImpl()109 void BoolArrayProperty::CreatePropImpl() {
110 GesturesPropBool orig_vals[count_];
111 memcpy(orig_vals, vals_, sizeof(orig_vals));
112 gprop_ = parent_->PropProvider()->create_bool_fn(
113 parent_->PropProviderData(),
114 name(),
115 vals_,
116 count_,
117 vals_);
118 if (delegate_ && memcmp(orig_vals, vals_, sizeof(orig_vals)))
119 delegate_->BoolArrayWasWritten(this);
120 }
121
NewValue() const122 Json::Value BoolArrayProperty::NewValue() const {
123 Json::Value list(Json::arrayValue);
124 for (size_t i = 0; i < count_; i++)
125 list.append(new Json::Value(vals_[i] != 0));
126 return list;
127 }
128
SetValue(const Json::Value & list)129 bool BoolArrayProperty::SetValue(const Json::Value& list) {
130 AssertWithReturnValue(list.type() == Json::arrayValue, false);
131 AssertWithReturnValue(list.size() == count_, false);
132
133 for (size_t i = 0; i < count_; i++) {
134 const Json::Value& elt_value = list[static_cast<int>(i)];
135 AssertWithReturnValue(elt_value.type() == Json::booleanValue, false);
136 vals_[i] = elt_value.asBool();
137 }
138
139 return true;
140 }
141
HandleGesturesPropWritten()142 void BoolArrayProperty::HandleGesturesPropWritten() {
143 // TODO(b/191802713): Log array property changes
144 if (delegate_)
145 delegate_->BoolArrayWasWritten(this);
146 }
147
CreatePropImpl()148 void DoubleProperty::CreatePropImpl() {
149 double orig_val = val_;
150 gprop_ = parent_->PropProvider()->create_real_fn(
151 parent_->PropProviderData(),
152 name(),
153 &val_,
154 1,
155 &val_);
156 if (delegate_ && orig_val != val_)
157 delegate_->DoubleWasWritten(this);
158 }
159
NewValue() const160 Json::Value DoubleProperty::NewValue() const {
161 return Json::Value(val_);
162 }
163
SetValue(const Json::Value & value)164 bool DoubleProperty::SetValue(const Json::Value& value) {
165 if (value.type() != Json::realValue &&
166 value.type() != Json::intValue &&
167 value.type() != Json::uintValue) {
168 return false;
169 }
170 val_ = value.asDouble();
171 return true;
172 }
173
HandleGesturesPropWritten()174 void DoubleProperty::HandleGesturesPropWritten() {
175 if (parent_ && parent_->activity_log()) {
176 ActivityLog::PropChangeEntry entry = {
177 name(), ActivityLog::PropChangeEntry::kDoubleProp, { 0 }
178 };
179 entry.value.double_val = val_;
180 parent_->activity_log()->LogPropChange(entry);
181 }
182 if (delegate_)
183 delegate_->DoubleWasWritten(this);
184 }
185
CreatePropImpl()186 void DoubleArrayProperty::CreatePropImpl() {
187 float orig_vals[count_];
188 memcpy(orig_vals, vals_, sizeof(orig_vals));
189 gprop_ = parent_->PropProvider()->create_real_fn(
190 parent_->PropProviderData(),
191 name(),
192 vals_,
193 count_,
194 vals_);
195 if (delegate_ && memcmp(orig_vals, vals_, sizeof(orig_vals)))
196 delegate_->DoubleArrayWasWritten(this);
197 }
198
NewValue() const199 Json::Value DoubleArrayProperty::NewValue() const {
200 Json::Value list(Json::arrayValue);
201 for (size_t i = 0; i < count_; i++) {
202 // Avoid infinity
203 double log_val = std::max(-1e30, std::min(vals_[i], 1e30));
204 list.append(Json::Value(log_val));
205 }
206 return list;
207 }
208
SetValue(const Json::Value & list)209 bool DoubleArrayProperty::SetValue(const Json::Value& list) {
210 AssertWithReturnValue(list.type() == Json::arrayValue, false);
211 AssertWithReturnValue(list.size() == count_, false);
212
213 for (size_t i = 0; i < count_; i++) {
214 Json::Value elt_value = list[static_cast<int>(i)];
215 AssertWithReturnValue(elt_value.type() == Json::realValue ||
216 elt_value.type() == Json::intValue ||
217 elt_value.type() == Json::uintValue, false);
218 vals_[i] = elt_value.asDouble();
219 }
220
221 return true;
222 }
223
HandleGesturesPropWritten()224 void DoubleArrayProperty::HandleGesturesPropWritten() {
225 // TODO(b/191802713): Log array property changes
226 if (delegate_)
227 delegate_->DoubleArrayWasWritten(this);
228 }
229
CreatePropImpl()230 void IntProperty::CreatePropImpl() {
231 int orig_val = val_;
232 gprop_ = parent_->PropProvider()->create_int_fn(
233 parent_->PropProviderData(),
234 name(),
235 &val_,
236 1,
237 &val_);
238 if (delegate_ && orig_val != val_)
239 delegate_->IntWasWritten(this);
240 }
241
NewValue() const242 Json::Value IntProperty::NewValue() const {
243 return Json::Value(val_);
244 }
245
SetValue(const Json::Value & value)246 bool IntProperty::SetValue(const Json::Value& value) {
247 if (value.type() != Json::intValue &&
248 value.type() != Json::uintValue) {
249 Err("Failing here %d", value.type());
250 return false;
251 }
252 val_ = value.asInt();
253 return true;
254 }
255
HandleGesturesPropWritten()256 void IntProperty::HandleGesturesPropWritten() {
257 if (parent_ && parent_->activity_log()) {
258 ActivityLog::PropChangeEntry entry = {
259 name(), ActivityLog::PropChangeEntry::kIntProp, { 0 }
260 };
261 entry.value.int_val = val_;
262 parent_->activity_log()->LogPropChange(entry);
263 }
264 if (delegate_)
265 delegate_->IntWasWritten(this);
266 }
267
CreatePropImpl()268 void IntArrayProperty::CreatePropImpl() {
269 int orig_vals[count_];
270 memcpy(orig_vals, vals_, sizeof(orig_vals));
271 gprop_ = parent_->PropProvider()->create_int_fn(
272 parent_->PropProviderData(),
273 name(),
274 vals_,
275 count_,
276 vals_);
277 if (delegate_ && memcmp(orig_vals, vals_, sizeof(orig_vals)))
278 delegate_->IntArrayWasWritten(this);
279 }
280
NewValue() const281 Json::Value IntArrayProperty::NewValue() const {
282 Json::Value list(Json::arrayValue);
283 for (size_t i = 0; i < count_; i++)
284 list.append(Json::Value(vals_[static_cast<int>(i)]));
285 return list;
286 }
287
SetValue(const Json::Value & list)288 bool IntArrayProperty::SetValue(const Json::Value& list) {
289 AssertWithReturnValue(list.type() == Json::arrayValue, false);
290 AssertWithReturnValue(list.size() == count_, false);
291
292 for (size_t i = 0; i < count_; i++) {
293 Json::Value elt_value = list[static_cast<int>(i)];
294 AssertWithReturnValue(elt_value.type() == Json::intValue ||
295 elt_value.type() == Json::uintValue, false);
296 vals_[i] = elt_value.asInt();
297 }
298
299 return true;
300 }
301
HandleGesturesPropWritten()302 void IntArrayProperty::HandleGesturesPropWritten() {
303 // TODO(b/191802713): Log array property changes
304 if (delegate_)
305 delegate_->IntArrayWasWritten(this);
306 }
307
CreatePropImpl()308 void StringProperty::CreatePropImpl() {
309 const char* orig_val = val_;
310 gprop_ = parent_->PropProvider()->create_string_fn(
311 parent_->PropProviderData(),
312 name(),
313 &val_,
314 val_);
315 if (delegate_ && strcmp(orig_val, val_) != 0)
316 delegate_->StringWasWritten(this);
317 }
318
NewValue() const319 Json::Value StringProperty::NewValue() const {
320 return Json::Value(val_);
321 }
322
SetValue(const Json::Value & value)323 bool StringProperty::SetValue(const Json::Value& value) {
324 if (value.type() != Json::stringValue) {
325 return false;
326 }
327 parsed_val_ = value.asString();
328 val_ = parsed_val_.c_str();
329 return true;
330 }
331
HandleGesturesPropWritten()332 void StringProperty::HandleGesturesPropWritten() {
333 if (delegate_)
334 delegate_->StringWasWritten(this);
335 }
336
337 } // namespace gestures
338