123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374 |
- // Copyright 2019 The Chromium Authors. All rights reserved.
- // Use of this source code is governed by a BSD-style license that can be
- // found in the LICENSE file.
- #include "ash/dbus/gesture_properties_service_provider.h"
- #include <memory>
- #include <utility>
- #include "base/bind.h"
- #include "base/logging.h"
- #include "dbus/message.h"
- #include "third_party/cros_system_api/dbus/service_constants.h"
- #include "ui/ozone/public/input_controller.h"
- #include "ui/ozone/public/ozone_platform.h"
- namespace ash {
- GesturePropertiesServiceProvider::GesturePropertiesServiceProvider()
- : weak_ptr_factory_(this) {}
- GesturePropertiesServiceProvider::~GesturePropertiesServiceProvider() = default;
- void GesturePropertiesServiceProvider::Start(
- scoped_refptr<dbus::ExportedObject> exported_object) {
- auto on_exported =
- base::BindRepeating(&GesturePropertiesServiceProvider::OnExported,
- weak_ptr_factory_.GetWeakPtr());
- exported_object->ExportMethod(
- chromeos::kGesturePropertiesServiceInterface,
- chromeos::kGesturePropertiesServiceListDevicesMethod,
- base::BindRepeating(&GesturePropertiesServiceProvider::ListDevices,
- weak_ptr_factory_.GetWeakPtr()),
- on_exported);
- exported_object->ExportMethod(
- chromeos::kGesturePropertiesServiceInterface,
- chromeos::kGesturePropertiesServiceListPropertiesMethod,
- base::BindRepeating(&GesturePropertiesServiceProvider::ListProperties,
- weak_ptr_factory_.GetWeakPtr()),
- on_exported);
- exported_object->ExportMethod(
- chromeos::kGesturePropertiesServiceInterface,
- chromeos::kGesturePropertiesServiceGetPropertyMethod,
- base::BindRepeating(&GesturePropertiesServiceProvider::GetProperty,
- weak_ptr_factory_.GetWeakPtr()),
- on_exported);
- exported_object->ExportMethod(
- chromeos::kGesturePropertiesServiceInterface,
- chromeos::kGesturePropertiesServiceSetPropertyMethod,
- base::BindRepeating(&GesturePropertiesServiceProvider::SetProperty,
- weak_ptr_factory_.GetWeakPtr()),
- on_exported);
- }
- void GesturePropertiesServiceProvider::OnExported(
- const std::string& interface_name,
- const std::string& method_name,
- bool success) {
- if (!success)
- LOG(ERROR) << "Failed to export " << interface_name << "." << method_name;
- }
- namespace {
- void GetPropertyCallback(dbus::MethodCall* method_call,
- std::unique_ptr<dbus::Response> response,
- dbus::ExportedObject::ResponseSender response_sender,
- bool is_read_only,
- ui::ozone::mojom::GesturePropValuePtr values) {
- if (values.is_null()) {
- std::move(response_sender)
- .Run(dbus::ErrorResponse::FromMethodCall(
- method_call, DBUS_ERROR_INVALID_ARGS,
- "The device ID or property name specified was not found."));
- return;
- }
- dbus::MessageWriter writer(response.get());
- dbus::MessageWriter variant_writer(nullptr);
- dbus::MessageWriter array_writer(nullptr);
- writer.AppendBool(is_read_only);
- switch (values->which()) {
- case ui::ozone::mojom::GesturePropValue::Tag::kInts: {
- writer.AppendUint32(values->get_ints().size());
- writer.OpenVariant("ai", &variant_writer);
- variant_writer.AppendArrayOfInt32s(values->get_ints().data(),
- values->get_ints().size());
- writer.CloseContainer(&variant_writer);
- break;
- }
- case ui::ozone::mojom::GesturePropValue::Tag::kShorts: {
- writer.AppendUint32(values->get_shorts().size());
- writer.OpenVariant("an", &variant_writer);
- variant_writer.OpenArray("n", &array_writer);
- for (int16_t value : values->get_shorts()) {
- array_writer.AppendInt16(value);
- }
- variant_writer.CloseContainer(&array_writer);
- writer.CloseContainer(&variant_writer);
- break;
- }
- case ui::ozone::mojom::GesturePropValue::Tag::kBools: {
- writer.AppendUint32(values->get_bools().size());
- writer.OpenVariant("ab", &variant_writer);
- variant_writer.OpenArray("b", &array_writer);
- for (bool value : values->get_bools()) {
- array_writer.AppendBool(value);
- }
- variant_writer.CloseContainer(&array_writer);
- writer.CloseContainer(&variant_writer);
- break;
- }
- case ui::ozone::mojom::GesturePropValue::Tag::kStr: {
- writer.AppendUint32(1);
- writer.AppendVariantOfString(values->get_str());
- break;
- }
- case ui::ozone::mojom::GesturePropValue::Tag::kReals: {
- writer.AppendUint32(values->get_reals().size());
- writer.OpenVariant("ad", &variant_writer);
- variant_writer.AppendArrayOfDoubles(values->get_reals().data(),
- values->get_reals().size());
- writer.CloseContainer(&variant_writer);
- break;
- }
- default: {
- // This should never happen.
- LOG(WARNING) << "No value set on GesturePropValue union; not returning "
- "values to GetProperty call.";
- writer.AppendUint32(0);
- break;
- }
- }
- std::move(response_sender).Run(std::move(response));
- }
- void SetPropertyCallback(dbus::MethodCall* method_call,
- dbus::ExportedObject::ResponseSender response_sender,
- ui::ozone::mojom::SetGesturePropErrorCode error) {
- std::string error_message;
- switch (error) {
- case ui::ozone::mojom::SetGesturePropErrorCode::SUCCESS:
- std::move(response_sender)
- .Run(dbus::Response::FromMethodCall(method_call));
- return;
- case ui::ozone::mojom::SetGesturePropErrorCode::NOT_FOUND:
- error_message = "The device ID or property name specified was not found.";
- break;
- case ui::ozone::mojom::SetGesturePropErrorCode::READ_ONLY:
- error_message = "That property is read-only.";
- break;
- case ui::ozone::mojom::SetGesturePropErrorCode::TYPE_MISMATCH:
- error_message =
- "The property is of a different type than the value(s) "
- "provided.";
- break;
- case ui::ozone::mojom::SetGesturePropErrorCode::SIZE_MISMATCH:
- error_message =
- "The property has a different number of values to that "
- "provided.";
- break;
- case ui::ozone::mojom::SetGesturePropErrorCode::UNKNOWN_ERROR:
- default:
- error_message = "An unknown error occurred.";
- break;
- }
- LOG(ERROR) << "SetProperty error: " << error_message;
- std::move(response_sender)
- .Run(dbus::ErrorResponse::FromMethodCall(
- method_call, DBUS_ERROR_INVALID_ARGS, error_message));
- }
- void ListDevicesCallback(std::unique_ptr<dbus::Response> response,
- dbus::ExportedObject::ResponseSender response_sender,
- const base::flat_map<int, std::string>& result) {
- dbus::MessageWriter writer(response.get());
- writer.AppendUint32(result.size());
- dbus::MessageWriter dict_writer(nullptr);
- writer.OpenArray("{is}", &dict_writer);
- for (const auto& pair : result) {
- dbus::MessageWriter dict_entry_writer(nullptr);
- dict_writer.OpenDictEntry(&dict_entry_writer);
- dict_entry_writer.AppendInt32(pair.first);
- dict_entry_writer.AppendString(pair.second);
- dict_writer.CloseContainer(&dict_entry_writer);
- }
- writer.CloseContainer(&dict_writer);
- std::move(response_sender).Run(std::move(response));
- }
- void ListPropertiesCallback(
- std::unique_ptr<dbus::Response> response,
- dbus::ExportedObject::ResponseSender response_sender,
- const std::vector<std::string>& result) {
- dbus::MessageWriter writer(response.get());
- writer.AppendUint32(result.size());
- writer.AppendArrayOfStrings(result);
- std::move(response_sender).Run(std::move(response));
- }
- } // namespace
- void GesturePropertiesServiceProvider::ListDevices(
- dbus::MethodCall* method_call,
- dbus::ExportedObject::ResponseSender response_sender) {
- std::unique_ptr<dbus::Response> response =
- dbus::Response::FromMethodCall(method_call);
- GetService()->ListDevices(base::BindOnce(
- &ListDevicesCallback, std::move(response), std::move(response_sender)));
- }
- void GesturePropertiesServiceProvider::ListProperties(
- dbus::MethodCall* method_call,
- dbus::ExportedObject::ResponseSender response_sender) {
- dbus::MessageReader reader(method_call);
- int32_t device_id;
- if (!reader.PopInt32(&device_id)) {
- std::move(response_sender)
- .Run(dbus::ErrorResponse::FromMethodCall(
- method_call, DBUS_ERROR_INVALID_ARGS,
- "The device ID (int32) is missing."));
- return;
- }
- std::unique_ptr<dbus::Response> response =
- dbus::Response::FromMethodCall(method_call);
- GetService()->ListProperties(
- device_id, base::BindOnce(&ListPropertiesCallback, std::move(response),
- std::move(response_sender)));
- }
- void GesturePropertiesServiceProvider::GetProperty(
- dbus::MethodCall* method_call,
- dbus::ExportedObject::ResponseSender response_sender) {
- dbus::MessageReader reader(method_call);
- int32_t device_id;
- std::string property_name;
- if (!reader.PopInt32(&device_id) || !reader.PopString(&property_name)) {
- std::move(response_sender)
- .Run(dbus::ErrorResponse::FromMethodCall(
- method_call, DBUS_ERROR_INVALID_ARGS,
- "The device ID (int32) and/or property name (string) is missing."));
- return;
- }
- std::unique_ptr<dbus::Response> response =
- dbus::Response::FromMethodCall(method_call);
- GetService()->GetProperty(
- device_id, property_name,
- base::BindOnce(&GetPropertyCallback, method_call, std::move(response),
- std::move(response_sender)));
- }
- static ui::ozone::mojom::GesturePropValuePtr GesturePropValueFromVariant(
- dbus::MessageReader* variant_reader,
- std::string* error_message) {
- std::string string_value;
- if (variant_reader->PopString(&string_value)) {
- return ui::ozone::mojom::GesturePropValue::NewStr(string_value);
- }
- dbus::MessageReader array_reader(nullptr);
- if (!variant_reader->PopArray(&array_reader)) {
- *error_message =
- "Value(s) should be specified either as a string or an "
- "array of the appropriate type.";
- return nullptr;
- }
- switch (array_reader.GetDataType()) {
- case dbus::Message::DataType::INT32: {
- std::vector<int32_t> values = {};
- int32_t value;
- while (array_reader.PopInt32(&value)) {
- values.push_back(value);
- }
- return ui::ozone::mojom::GesturePropValue::NewInts(values);
- }
- case dbus::Message::DataType::INT16: {
- std::vector<int16_t> values = {};
- int16_t value;
- while (array_reader.PopInt16(&value)) {
- values.push_back(value);
- }
- return ui::ozone::mojom::GesturePropValue::NewShorts(values);
- }
- case dbus::Message::DataType::BOOL: {
- std::vector<bool> values = {};
- bool value;
- while (array_reader.PopBool(&value)) {
- values.push_back(value);
- }
- return ui::ozone::mojom::GesturePropValue::NewBools(values);
- }
- case dbus::Message::DataType::DOUBLE: {
- std::vector<double> values = {};
- double value;
- while (array_reader.PopDouble(&value)) {
- values.push_back(value);
- }
- return ui::ozone::mojom::GesturePropValue::NewReals(values);
- }
- case dbus::Message::DataType::STRING: {
- *error_message =
- "String properties can only have one value, and so "
- "should not be specified as arrays.";
- return nullptr;
- }
- default: {
- *error_message =
- "Unsupported D-Bus value type; supported types are "
- "int32, int16, bool, double, and string.";
- return nullptr;
- }
- }
- }
- void GesturePropertiesServiceProvider::SetProperty(
- dbus::MethodCall* method_call,
- dbus::ExportedObject::ResponseSender response_sender) {
- dbus::MessageReader reader(method_call);
- int32_t device_id;
- std::string property_name;
- if (!reader.PopInt32(&device_id) || !reader.PopString(&property_name)) {
- std::move(response_sender)
- .Run(dbus::ErrorResponse::FromMethodCall(
- method_call, DBUS_ERROR_INVALID_ARGS,
- "The device ID (int32) and/or property name (string) is missing."));
- return;
- }
- if (!reader.HasMoreData()) {
- std::move(response_sender)
- .Run(dbus::ErrorResponse::FromMethodCall(
- method_call, DBUS_ERROR_INVALID_ARGS, "No value(s) specified."));
- return;
- }
- std::string error_message;
- ui::ozone::mojom::GesturePropValuePtr values =
- GesturePropValueFromVariant(&reader, &error_message);
- if (values.is_null()) {
- std::move(response_sender)
- .Run(dbus::ErrorResponse::FromMethodCall(
- method_call, DBUS_ERROR_INVALID_ARGS, error_message));
- return;
- }
- GetService()->SetProperty(device_id, property_name, std::move(values),
- base::BindOnce(&SetPropertyCallback, method_call,
- std::move(response_sender)));
- }
- ui::ozone::mojom::GesturePropertiesService*
- GesturePropertiesServiceProvider::GetService() {
- if (service_for_test_ != nullptr)
- return service_for_test_;
- if (!service_.is_bound()) {
- ui::OzonePlatform::GetInstance()
- ->GetInputController()
- ->GetGesturePropertiesService(service_.BindNewPipeAndPassReceiver());
- }
- return service_.get();
- }
- } // namespace ash
|