xref: /aosp_15_r20/external/libchrome-gestures/src/prop_registry.cc (revision aed3e5085e770be5b69ce25295ecf6ddf906af95)
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_ = nullptr;
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(), { val_ }
101     };
102     parent_->activity_log()->LogPropChange(entry);
103   }
104   if (delegate_)
105     delegate_->BoolWasWritten(this);
106 }
107 
CreatePropImpl()108 void BoolArrayProperty::CreatePropImpl() {
109   auto orig_vals = std::make_unique<GesturesPropBool[]>(count_);
110 
111   memcpy(orig_vals.get(), vals_, count_ * sizeof(GesturesPropBool));
112   gprop_ = parent_->PropProvider()->create_bool_fn(
113       parent_->PropProviderData(),
114       name(),
115       vals_,
116       count_,
117       vals_);
118   if (delegate_ && memcmp(orig_vals.get(), vals_,
119                           count_ * sizeof(GesturesPropBool)))
120     delegate_->BoolArrayWasWritten(this);
121 }
122 
NewValue() const123 Json::Value BoolArrayProperty::NewValue() const {
124   Json::Value list(Json::arrayValue);
125   for (size_t i = 0; i < count_; i++)
126     list.append(Json::Value(vals_[i] != 0));
127   return list;
128 }
129 
SetValue(const Json::Value & list)130 bool BoolArrayProperty::SetValue(const Json::Value& list) {
131   AssertWithReturnValue(list.type() == Json::arrayValue, false);
132   AssertWithReturnValue(list.size() == count_, false);
133 
134   for (size_t i = 0; i < count_; i++) {
135     const Json::Value& elt_value = list[static_cast<int>(i)];
136     AssertWithReturnValue(elt_value.type() == Json::booleanValue, false);
137     vals_[i] = elt_value.asBool();
138   }
139 
140   return true;
141 }
142 
HandleGesturesPropWritten()143 void BoolArrayProperty::HandleGesturesPropWritten() {
144   // TODO(b/191802713): Log array property changes
145   if (delegate_)
146     delegate_->BoolArrayWasWritten(this);
147 }
148 
CreatePropImpl()149 void DoubleProperty::CreatePropImpl() {
150   double orig_val = val_;
151   gprop_ = parent_->PropProvider()->create_real_fn(
152       parent_->PropProviderData(),
153       name(),
154       &val_,
155       1,
156       &val_);
157   if (delegate_ && orig_val != val_)
158     delegate_->DoubleWasWritten(this);
159 }
160 
NewValue() const161 Json::Value DoubleProperty::NewValue() const {
162   return Json::Value(val_);
163 }
164 
SetValue(const Json::Value & value)165 bool DoubleProperty::SetValue(const Json::Value& value) {
166   if (value.type() != Json::realValue &&
167       value.type() != Json::intValue &&
168       value.type() != Json::uintValue) {
169     return false;
170   }
171   val_ = value.asDouble();
172   return true;
173 }
174 
HandleGesturesPropWritten()175 void DoubleProperty::HandleGesturesPropWritten() {
176   if (parent_ && parent_->activity_log()) {
177     ActivityLog::PropChangeEntry entry = {
178       name(), { val_ }
179     };
180     parent_->activity_log()->LogPropChange(entry);
181   }
182   if (delegate_)
183     delegate_->DoubleWasWritten(this);
184 }
185 
CreatePropImpl()186 void DoubleArrayProperty::CreatePropImpl() {
187   auto orig_vals = std::make_unique<float[]>(count_);
188 
189   memcpy(orig_vals.get(), vals_, count_ * sizeof(float));
190   gprop_ = parent_->PropProvider()->create_real_fn(
191       parent_->PropProviderData(),
192       name(),
193       vals_,
194       count_,
195       vals_);
196   if (delegate_ && memcmp(orig_vals.get(), vals_, count_ * sizeof(float)))
197     delegate_->DoubleArrayWasWritten(this);
198 }
199 
NewValue() const200 Json::Value DoubleArrayProperty::NewValue() const {
201   Json::Value list(Json::arrayValue);
202   for (size_t i = 0; i < count_; i++) {
203     // Avoid infinity
204     double log_val = std::max(-1e30, std::min(vals_[i], 1e30));
205     list.append(Json::Value(log_val));
206   }
207   return list;
208 }
209 
SetValue(const Json::Value & list)210 bool DoubleArrayProperty::SetValue(const Json::Value& list) {
211   AssertWithReturnValue(list.type() == Json::arrayValue, false);
212   AssertWithReturnValue(list.size() == count_, false);
213 
214   for (size_t i = 0; i < count_; i++) {
215     Json::Value elt_value = list[static_cast<int>(i)];
216     AssertWithReturnValue(elt_value.type() == Json::realValue ||
217                           elt_value.type() == Json::intValue ||
218                           elt_value.type() == Json::uintValue, false);
219     vals_[i] = elt_value.asDouble();
220   }
221 
222   return true;
223 }
224 
HandleGesturesPropWritten()225 void DoubleArrayProperty::HandleGesturesPropWritten() {
226   // TODO(b/191802713): Log array property changes
227   if (delegate_)
228     delegate_->DoubleArrayWasWritten(this);
229 }
230 
CreatePropImpl()231 void IntProperty::CreatePropImpl() {
232   int orig_val = val_;
233   gprop_ = parent_->PropProvider()->create_int_fn(
234       parent_->PropProviderData(),
235       name(),
236       &val_,
237       1,
238       &val_);
239   if (delegate_ && orig_val != val_)
240     delegate_->IntWasWritten(this);
241 }
242 
NewValue() const243 Json::Value IntProperty::NewValue() const {
244   return Json::Value(val_);
245 }
246 
SetValue(const Json::Value & value)247 bool IntProperty::SetValue(const Json::Value& value) {
248   if (value.type() != Json::intValue &&
249       value.type() != Json::uintValue) {
250     Err("Failing here %d", value.type());
251     return false;
252   }
253   val_ = value.asInt();
254   return true;
255 }
256 
HandleGesturesPropWritten()257 void IntProperty::HandleGesturesPropWritten() {
258   if (parent_ && parent_->activity_log()) {
259     ActivityLog::PropChangeEntry entry = {
260       name(), { val_ }
261     };
262     parent_->activity_log()->LogPropChange(entry);
263   }
264   if (delegate_)
265     delegate_->IntWasWritten(this);
266 }
267 
CreatePropImpl()268 void IntArrayProperty::CreatePropImpl() {
269   auto orig_vals = std::make_unique<int[]>(count_);
270 
271   memcpy(orig_vals.get(), vals_, count_ * sizeof(int));
272   gprop_ = parent_->PropProvider()->create_int_fn(
273       parent_->PropProviderData(),
274       name(),
275       vals_,
276       count_,
277       vals_);
278   if (delegate_ && memcmp(orig_vals.get(), vals_, count_ * sizeof(int)))
279     delegate_->IntArrayWasWritten(this);
280 }
281 
NewValue() const282 Json::Value IntArrayProperty::NewValue() const {
283   Json::Value list(Json::arrayValue);
284   for (size_t i = 0; i < count_; i++)
285     list.append(Json::Value(vals_[static_cast<int>(i)]));
286   return list;
287 }
288 
SetValue(const Json::Value & list)289 bool IntArrayProperty::SetValue(const Json::Value& list) {
290   AssertWithReturnValue(list.type() == Json::arrayValue, false);
291   AssertWithReturnValue(list.size() == count_, false);
292 
293   for (size_t i = 0; i < count_; i++) {
294     Json::Value elt_value = list[static_cast<int>(i)];
295     AssertWithReturnValue(elt_value.type() == Json::intValue ||
296                           elt_value.type() == Json::uintValue, false);
297     vals_[i] = elt_value.asInt();
298   }
299 
300   return true;
301 }
302 
HandleGesturesPropWritten()303 void IntArrayProperty::HandleGesturesPropWritten() {
304   // TODO(b/191802713): Log array property changes
305   if (delegate_)
306     delegate_->IntArrayWasWritten(this);
307 }
308 
CreatePropImpl()309 void StringProperty::CreatePropImpl() {
310   const char* orig_val = val_;
311   gprop_ = parent_->PropProvider()->create_string_fn(
312       parent_->PropProviderData(),
313       name(),
314       &val_,
315       val_);
316   if (delegate_ && strcmp(orig_val, val_) != 0)
317     delegate_->StringWasWritten(this);
318 }
319 
NewValue() const320 Json::Value StringProperty::NewValue() const {
321   return Json::Value(val_);
322 }
323 
SetValue(const Json::Value & value)324 bool StringProperty::SetValue(const Json::Value& value) {
325   if (value.type() != Json::stringValue) {
326     return false;
327   }
328   parsed_val_ = value.asString();
329   val_ = parsed_val_.c_str();
330   return true;
331 }
332 
HandleGesturesPropWritten()333 void StringProperty::HandleGesturesPropWritten() {
334   if (delegate_)
335     delegate_->StringWasWritten(this);
336 }
337 
338 }  // namespace gestures
339