1 // Copyright 2019 The Chromium Authors. All rights reserved.
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 "ui/events/ozone/evdev/libgestures_glue/gesture_properties_service.h"
6 
7 #include <utility>
8 
9 namespace ui {
10 
11 namespace {
12 
13 using ozone::mojom::GesturePropValue;
14 
GesturePropValueFromProp(GesturesProp * prop)15 ozone::mojom::GesturePropValuePtr GesturePropValueFromProp(GesturesProp* prop) {
16   if (prop == nullptr) {
17     return nullptr;
18   }
19   switch (prop->type()) {
20     case GesturesProp::PropertyType::PT_INT:
21       return GesturePropValue::NewInts(prop->GetIntValue());
22     case GesturesProp::PropertyType::PT_SHORT:
23       return GesturePropValue::NewShorts(prop->GetShortValue());
24     case GesturesProp::PropertyType::PT_BOOL:
25       return GesturePropValue::NewBools(prop->GetBoolValue());
26     case GesturesProp::PropertyType::PT_STRING:
27       return GesturePropValue::NewStr(prop->GetStringValue());
28     case GesturesProp::PropertyType::PT_REAL:
29       return GesturePropValue::NewReals(prop->GetDoubleValue());
30   }
31 }
32 
PropertyTypeMatchesValues(ui::GesturePropertyProvider::PropertyType type,GesturePropValue::Tag values_tag)33 bool PropertyTypeMatchesValues(ui::GesturePropertyProvider::PropertyType type,
34                                GesturePropValue::Tag values_tag) {
35   switch (type) {
36     case ui::GesturePropertyProvider::PT_INT:
37       return values_tag == GesturePropValue::Tag::INTS;
38     case ui::GesturePropertyProvider::PT_SHORT:
39       return values_tag == GesturePropValue::Tag::SHORTS;
40     case ui::GesturePropertyProvider::PT_BOOL:
41       return values_tag == GesturePropValue::Tag::BOOLS;
42     case ui::GesturePropertyProvider::PT_STRING:
43       return values_tag == GesturePropValue::Tag::STR;
44     case ui::GesturePropertyProvider::PT_REAL:
45       return values_tag == GesturePropValue::Tag::REALS;
46   }
47   // This should never happen.
48   return false;
49 }
50 
TrySetPropertyValues(GesturesProp * property,ozone::mojom::GesturePropValuePtr values)51 bool TrySetPropertyValues(GesturesProp* property,
52                           ozone::mojom::GesturePropValuePtr values) {
53   switch (property->type()) {
54     case ui::GesturePropertyProvider::PT_INT:
55       return property->SetIntValue(values->get_ints());
56     case ui::GesturePropertyProvider::PT_SHORT:
57       return property->SetShortValue(values->get_shorts());
58     case ui::GesturePropertyProvider::PT_BOOL:
59       return property->SetBoolValue(values->get_bools());
60     case ui::GesturePropertyProvider::PT_STRING:
61       return property->SetStringValue(values->get_str());
62     case ui::GesturePropertyProvider::PT_REAL:
63       return property->SetDoubleValue(values->get_reals());
64   }
65 }
66 
67 }  // namespace
68 
GesturePropertiesService(GesturePropertyProvider * provider,mojo::PendingReceiver<ozone::mojom::GesturePropertiesService> receiver)69 GesturePropertiesService::GesturePropertiesService(
70     GesturePropertyProvider* provider,
71     mojo::PendingReceiver<ozone::mojom::GesturePropertiesService> receiver)
72     : prop_provider_(provider), receiver_(this, std::move(receiver)) {}
73 
ListDevices(ListDevicesCallback reply)74 void GesturePropertiesService::ListDevices(ListDevicesCallback reply) {
75   base::flat_map<int, std::string> response = {};
76   std::vector<int> ids;
77   prop_provider_->GetDeviceIdsByType(DT_ALL, &ids);
78   for (size_t i = 0; i < ids.size(); ++i) {
79     response.emplace(ids[i], prop_provider_->GetDeviceNameById(ids[i]));
80   }
81   std::move(reply).Run(response);
82 }
83 
ListProperties(int device_id,ListPropertiesCallback reply)84 void GesturePropertiesService::ListProperties(int device_id,
85                                               ListPropertiesCallback reply) {
86   std::vector<std::string> response =
87       prop_provider_->GetPropertyNamesById(device_id);
88   std::move(reply).Run(response);
89 }
90 
GetProperty(int device_id,const std::string & name,GetPropertyCallback reply)91 void GesturePropertiesService::GetProperty(int device_id,
92                                            const std::string& name,
93                                            GetPropertyCallback reply) {
94   bool is_read_only = true;
95   GesturesProp* property = prop_provider_->GetProperty(device_id, name);
96   ozone::mojom::GesturePropValuePtr prop_value =
97       GesturePropValueFromProp(property);
98   if (property != nullptr) {
99     is_read_only = property->IsReadOnly();
100   }
101   std::move(reply).Run(is_read_only, std::move(prop_value));
102 }
103 
SetProperty(int device_id,const std::string & name,ozone::mojom::GesturePropValuePtr values,SetPropertyCallback reply)104 void GesturePropertiesService::SetProperty(
105     int device_id,
106     const std::string& name,
107     ozone::mojom::GesturePropValuePtr values,
108     SetPropertyCallback reply) {
109   GesturesProp* property = prop_provider_->GetProperty(device_id, name);
110   if (property == NULL) {
111     std::move(reply).Run(ozone::mojom::SetGesturePropErrorCode::NOT_FOUND);
112     return;
113   }
114   if (property->IsReadOnly()) {
115     std::move(reply).Run(ozone::mojom::SetGesturePropErrorCode::READ_ONLY);
116     return;
117   }
118   if (!PropertyTypeMatchesValues(property->type(), values->which())) {
119     std::move(reply).Run(ozone::mojom::SetGesturePropErrorCode::TYPE_MISMATCH);
120     return;
121   }
122   size_t num_values;
123   switch (values->which()) {
124     case ozone::mojom::GesturePropValue::Tag::INTS:
125       num_values = values->get_ints().size();
126       break;
127     case ozone::mojom::GesturePropValue::Tag::SHORTS:
128       num_values = values->get_shorts().size();
129       break;
130     case ozone::mojom::GesturePropValue::Tag::BOOLS:
131       num_values = values->get_bools().size();
132       break;
133     case ozone::mojom::GesturePropValue::Tag::STR:
134       num_values = 1;
135       break;
136     case ozone::mojom::GesturePropValue::Tag::REALS:
137       num_values = values->get_reals().size();
138       break;
139   }
140   if (num_values != property->count()) {
141     std::move(reply).Run(ozone::mojom::SetGesturePropErrorCode::SIZE_MISMATCH);
142     return;
143   }
144 
145   bool did_set = TrySetPropertyValues(property, std::move(values));
146   std::move(reply).Run(
147       did_set ? ozone::mojom::SetGesturePropErrorCode::SUCCESS
148               : ozone::mojom::SetGesturePropErrorCode::UNKNOWN_ERROR);
149 }
150 
151 }  // namespace ui
152