| Index: chromeos/dbus/fake_bluetooth_media_transport_client.cc
|
| diff --git a/chromeos/dbus/fake_bluetooth_media_transport_client.cc b/chromeos/dbus/fake_bluetooth_media_transport_client.cc
|
| index d503aa04d6b36894868e7ad9ae8cd296f1976637..01822f96d733ae10359e0b3d0cbaf6a01be3f506 100644
|
| --- a/chromeos/dbus/fake_bluetooth_media_transport_client.cc
|
| +++ b/chromeos/dbus/fake_bluetooth_media_transport_client.cc
|
| @@ -4,6 +4,9 @@
|
|
|
| #include "chromeos/dbus/fake_bluetooth_media_transport_client.h"
|
|
|
| +#include <unistd.h>
|
| +#include <sys/socket.h>
|
| +
|
| #include <sstream>
|
|
|
| #include "base/bind.h"
|
| @@ -13,6 +16,7 @@
|
| #include "chromeos/dbus/fake_bluetooth_adapter_client.h"
|
| #include "chromeos/dbus/fake_bluetooth_media_client.h"
|
| #include "chromeos/dbus/fake_bluetooth_media_endpoint_service_provider.h"
|
| +#include "dbus/file_descriptor.h"
|
|
|
| using dbus::ObjectPath;
|
|
|
| @@ -21,6 +25,13 @@ namespace {
|
| // TODO(mcchou): Remove this constants once it is in cros_system_api.
|
| const char kBluetoothMediaTransportInterface[] = "org.bluez.MediaTransport1";
|
| const char kNotImplemented[] = "org.bluez.NotImplemented";
|
| +const char kNotAuthorized[] = "org.bluez.NotAuthorized";
|
| +const char kFailed[] = "org.bluez.Failed";
|
| +const char kNotAvailable[] = "org.bluez.NotAvailable";
|
| +
|
| +const int kInvalidFd = -1;
|
| +const uint16_t kReadMtu = 20;
|
| +const uint16_t kWriteMtu = 25;
|
|
|
| ObjectPath GenerateTransportPath() {
|
| static unsigned int sequence_number = 0;
|
| @@ -89,9 +100,7 @@ FakeBluetoothMediaTransportClient::FakeBluetoothMediaTransportClient() {
|
| }
|
|
|
| FakeBluetoothMediaTransportClient::~FakeBluetoothMediaTransportClient() {
|
| - for (auto& it : endpoint_to_transport_map_)
|
| - delete it.second;
|
| - endpoint_to_transport_map_.clear();
|
| + STLDeleteValues(&endpoint_to_transport_map_);
|
| }
|
|
|
| // DBusClient override.
|
| @@ -109,27 +118,29 @@ void FakeBluetoothMediaTransportClient::RemoveObserver(
|
| }
|
|
|
| FakeBluetoothMediaTransportClient::Properties*
|
| - FakeBluetoothMediaTransportClient::GetProperties(
|
| - const ObjectPath& object_path) {
|
| - ObjectPath endpoint_path = GetEndpointPath(object_path);
|
| - if (!endpoint_path.IsValid() ||
|
| - !ContainsKey(endpoint_to_transport_map_, endpoint_path))
|
| +FakeBluetoothMediaTransportClient::GetProperties(
|
| + const ObjectPath& object_path) {
|
| + const ObjectPath& endpoint_path = GetEndpointPath(object_path);
|
| + Transport* transport = GetTransport(endpoint_path);
|
| + if (!transport)
|
| return nullptr;
|
| - return endpoint_to_transport_map_[endpoint_path]->properties.get();
|
| + return transport->properties.get();
|
| }
|
|
|
| void FakeBluetoothMediaTransportClient::Acquire(
|
| const ObjectPath& object_path,
|
| const AcquireCallback& callback,
|
| const ErrorCallback& error_callback) {
|
| - error_callback.Run(kNotImplemented, "");
|
| + VLOG(1) << "Acquire - transport path: " << object_path.value();
|
| + AcquireDelegate(false, object_path, callback, error_callback);
|
| }
|
|
|
| void FakeBluetoothMediaTransportClient::TryAcquire(
|
| const ObjectPath& object_path,
|
| const AcquireCallback& callback,
|
| const ErrorCallback& error_callback) {
|
| - error_callback.Run(kNotImplemented, "");
|
| + VLOG(1) << "TryAcquire - transport path: " << object_path.value();
|
| + AcquireDelegate(true, object_path, callback, error_callback);
|
| }
|
|
|
| void FakeBluetoothMediaTransportClient::Release(
|
| @@ -174,64 +185,142 @@ void FakeBluetoothMediaTransportClient::SetValid(
|
| return;
|
| }
|
|
|
| - if (!ContainsKey(endpoint_to_transport_map_, endpoint_path))
|
| + Transport* transport = GetTransport(endpoint_path);
|
| + if (!transport)
|
| return;
|
| + ObjectPath transport_path = transport->path;
|
|
|
| // Notifies observers about the state change of the transport.
|
| FOR_EACH_OBSERVER(BluetoothMediaTransportClient::Observer, observers_,
|
| - MediaTransportRemoved(GetTransportPath(endpoint_path)));
|
| + MediaTransportRemoved(transport_path));
|
|
|
| - endpoint->ClearConfiguration(GetTransportPath(endpoint_path));
|
| - transport_to_endpoint_map_.erase(GetTransportPath(endpoint_path));
|
| - delete endpoint_to_transport_map_[endpoint_path];
|
| + endpoint->ClearConfiguration(transport_path);
|
| + delete transport;
|
| endpoint_to_transport_map_.erase(endpoint_path);
|
| + transport_to_endpoint_map_.erase(transport_path);
|
| }
|
|
|
| void FakeBluetoothMediaTransportClient::SetState(
|
| - const dbus::ObjectPath& endpoint_path,
|
| + const ObjectPath& endpoint_path,
|
| const std::string& state) {
|
| - if (!ContainsKey(endpoint_to_transport_map_, endpoint_path))
|
| + VLOG(1) << "SetState - state: " << state;
|
| +
|
| + Transport* transport = GetTransport(endpoint_path);
|
| + if (!transport)
|
| return;
|
|
|
| - endpoint_to_transport_map_[endpoint_path]
|
| - ->properties->state.ReplaceValue(state);
|
| + transport->properties->state.ReplaceValue(state);
|
| FOR_EACH_OBSERVER(BluetoothMediaTransportClient::Observer, observers_,
|
| MediaTransportPropertyChanged(
|
| - GetTransportPath(endpoint_path),
|
| + transport->path,
|
| BluetoothMediaTransportClient::kStateProperty));
|
| }
|
|
|
| void FakeBluetoothMediaTransportClient::SetVolume(
|
| - const dbus::ObjectPath& endpoint_path,
|
| + const ObjectPath& endpoint_path,
|
| const uint16_t& volume) {
|
| - if (!ContainsKey(endpoint_to_transport_map_, endpoint_path))
|
| + Transport* transport = GetTransport(endpoint_path);
|
| + if (!transport)
|
| return;
|
|
|
| - endpoint_to_transport_map_[endpoint_path]->properties->volume.ReplaceValue(
|
| - volume);
|
| + transport->properties->volume.ReplaceValue(volume);
|
| FOR_EACH_OBSERVER(BluetoothMediaTransportClient::Observer, observers_,
|
| MediaTransportPropertyChanged(
|
| - GetTransportPath(endpoint_path),
|
| + transport->path,
|
| BluetoothMediaTransportClient::kVolumeProperty));
|
| }
|
|
|
| +void FakeBluetoothMediaTransportClient::WriteData(
|
| + const ObjectPath& endpoint_path, const std::vector<char>& bytes) {
|
| + VLOG(1) << "WriteData - write " << bytes.size() << " bytes";
|
| +
|
| + Transport* transport = GetTransport(endpoint_path);
|
| +
|
| + if (!transport || transport->properties->state.value() != "active") {
|
| + VLOG(1) << "WriteData - write operation rejected, since the state isn't "
|
| + "active for endpoint: " << endpoint_path.value();
|
| + return;
|
| + }
|
| +
|
| + if (!transport->input_fd.get()) {
|
| + VLOG(1) << "WriteData - invalid input file descriptor";
|
| + return;
|
| + }
|
| +
|
| + ssize_t written_len =
|
| + write(transport->input_fd->GetPlatformFile(), bytes.data(), bytes.size());
|
| + if (written_len < 0) {
|
| + VLOG(1) << "WriteData - failed to write to the socket";
|
| + return;
|
| + }
|
| +
|
| + VLOG(1) << "WriteData - wrote " << written_len << " bytes to the socket";
|
| +}
|
| +
|
| ObjectPath FakeBluetoothMediaTransportClient::GetTransportPath(
|
| const ObjectPath& endpoint_path) {
|
| - if (ContainsKey(endpoint_to_transport_map_, endpoint_path))
|
| - return endpoint_to_transport_map_[endpoint_path]->path;
|
| - return ObjectPath("");
|
| + Transport* transport = GetTransport(endpoint_path);
|
| + return transport ? transport->path : ObjectPath("");
|
| +}
|
| +
|
| +void FakeBluetoothMediaTransportClient::OnPropertyChanged(
|
| + const std::string& property_name) {
|
| + VLOG(1) << "Property " << property_name << " changed";
|
| }
|
|
|
| ObjectPath FakeBluetoothMediaTransportClient::GetEndpointPath(
|
| const ObjectPath& transport_path) {
|
| - if (ContainsKey(transport_to_endpoint_map_, transport_path))
|
| - return transport_to_endpoint_map_[transport_path];
|
| - return ObjectPath("");
|
| + const auto& it = transport_to_endpoint_map_.find(transport_path);
|
| + return it != transport_to_endpoint_map_.end() ? it->second : ObjectPath("");
|
| }
|
|
|
| -void FakeBluetoothMediaTransportClient::OnPropertyChanged(
|
| - const std::string& property_name) {
|
| - VLOG(1) << "Property " << property_name << " changed";
|
| +FakeBluetoothMediaTransportClient::Transport*
|
| +FakeBluetoothMediaTransportClient::GetTransport(
|
| + const ObjectPath& endpoint_path) {
|
| + const auto& it = endpoint_to_transport_map_.find(endpoint_path);
|
| + return (it != endpoint_to_transport_map_.end()) ? it->second : nullptr;
|
| +}
|
| +
|
| +FakeBluetoothMediaTransportClient::Transport*
|
| +FakeBluetoothMediaTransportClient::GetTransportByPath(
|
| + const dbus::ObjectPath& transport_path) {
|
| + return GetTransport(GetEndpointPath(transport_path));
|
| +}
|
| +
|
| +void FakeBluetoothMediaTransportClient::AcquireDelegate(
|
| + bool try_flag,
|
| + const ObjectPath& object_path,
|
| + const AcquireCallback& callback,
|
| + const ErrorCallback& error_callback) {
|
| + const ObjectPath& endpoint_path = GetEndpointPath(object_path);
|
| + Transport* transport = GetTransport(endpoint_path);
|
| + if (!transport) {
|
| + error_callback.Run(kFailed, "");
|
| + return;
|
| + }
|
| +
|
| + std::string state = transport->properties->state.value();
|
| + if (state == "active") {
|
| + error_callback.Run(kNotAuthorized, "");
|
| + return;
|
| + }
|
| + if (state != "pending") {
|
| + error_callback.Run(try_flag ? kNotAvailable : kFailed, "");
|
| + return;
|
| + }
|
| +
|
| + int fds[2];
|
| + if (socketpair(AF_UNIX, SOCK_STREAM, 0, fds) < 0) {
|
| + transport->input_fd.reset();
|
| + error_callback.Run(kFailed, "");
|
| + return;
|
| + }
|
| + DCHECK((fds[0] > kInvalidFd) && (fds[1] > kInvalidFd));
|
| + transport->input_fd.reset(new base::File(fds[0]));
|
| +
|
| + dbus::FileDescriptor out_fd(fds[1]);
|
| + callback.Run(&out_fd, kReadMtu, kWriteMtu);
|
| + SetState(endpoint_path, "active");
|
| }
|
|
|
| } // namespace chromeos
|
|
|