hid_connection_impl.cc 5.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151
  1. // Copyright 2017 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. #include "services/device/hid/hid_connection_impl.h"
  5. #include "base/bind.h"
  6. #include "base/memory/ref_counted_memory.h"
  7. namespace device {
  8. // static
  9. void HidConnectionImpl::Create(
  10. scoped_refptr<device::HidConnection> connection,
  11. mojo::PendingReceiver<mojom::HidConnection> receiver,
  12. mojo::PendingRemote<mojom::HidConnectionClient> connection_client,
  13. mojo::PendingRemote<mojom::HidConnectionWatcher> watcher) {
  14. // This HidConnectionImpl is owned by |receiver| and |watcher|.
  15. new HidConnectionImpl(connection, std::move(receiver),
  16. std::move(connection_client), std::move(watcher));
  17. }
  18. HidConnectionImpl::HidConnectionImpl(
  19. scoped_refptr<device::HidConnection> connection,
  20. mojo::PendingReceiver<mojom::HidConnection> receiver,
  21. mojo::PendingRemote<mojom::HidConnectionClient> connection_client,
  22. mojo::PendingRemote<mojom::HidConnectionWatcher> watcher)
  23. : receiver_(this, std::move(receiver)),
  24. hid_connection_(std::move(connection)),
  25. watcher_(std::move(watcher)) {
  26. receiver_.set_disconnect_handler(base::BindOnce(
  27. [](HidConnectionImpl* self) { delete self; }, base::Unretained(this)));
  28. if (watcher_) {
  29. watcher_.set_disconnect_handler(base::BindOnce(
  30. [](HidConnectionImpl* self) { delete self; }, base::Unretained(this)));
  31. }
  32. if (connection_client) {
  33. hid_connection_->SetClient(this);
  34. client_.Bind(std::move(connection_client));
  35. }
  36. }
  37. HidConnectionImpl::~HidConnectionImpl() {
  38. DCHECK(hid_connection_);
  39. hid_connection_->SetClient(nullptr);
  40. // Close |hid_connection_| on destruction. HidConnectionImpl is owned by
  41. // its mojom::HidConnection receiver and mojom::HidConnectionWatcher remote
  42. // and will self-destruct when either pipe is closed.
  43. hid_connection_->Close();
  44. }
  45. void HidConnectionImpl::OnInputReport(
  46. scoped_refptr<base::RefCountedBytes> buffer,
  47. size_t size) {
  48. DCHECK(client_);
  49. uint8_t report_id = buffer->data()[0];
  50. uint8_t* begin = &buffer->data()[1];
  51. uint8_t* end = buffer->data().data() + size;
  52. std::vector<uint8_t> data(begin, end);
  53. client_->OnInputReport(report_id, data);
  54. }
  55. void HidConnectionImpl::Read(ReadCallback callback) {
  56. DCHECK(hid_connection_);
  57. hid_connection_->Read(base::BindOnce(&HidConnectionImpl::OnRead,
  58. weak_factory_.GetWeakPtr(),
  59. std::move(callback)));
  60. }
  61. void HidConnectionImpl::OnRead(ReadCallback callback,
  62. bool success,
  63. scoped_refptr<base::RefCountedBytes> buffer,
  64. size_t size) {
  65. if (!success) {
  66. std::move(callback).Run(false, 0, absl::nullopt);
  67. return;
  68. }
  69. DCHECK(buffer);
  70. std::vector<uint8_t> data(buffer->front() + 1, buffer->front() + size);
  71. std::move(callback).Run(true, buffer->data()[0], data);
  72. }
  73. void HidConnectionImpl::Write(uint8_t report_id,
  74. const std::vector<uint8_t>& buffer,
  75. WriteCallback callback) {
  76. DCHECK(hid_connection_);
  77. auto io_buffer =
  78. base::MakeRefCounted<base::RefCountedBytes>(buffer.size() + 1);
  79. io_buffer->data()[0] = report_id;
  80. memcpy(io_buffer->front() + 1, buffer.data(), buffer.size());
  81. hid_connection_->Write(io_buffer, base::BindOnce(&HidConnectionImpl::OnWrite,
  82. weak_factory_.GetWeakPtr(),
  83. std::move(callback)));
  84. }
  85. void HidConnectionImpl::OnWrite(WriteCallback callback, bool success) {
  86. std::move(callback).Run(success);
  87. }
  88. void HidConnectionImpl::GetFeatureReport(uint8_t report_id,
  89. GetFeatureReportCallback callback) {
  90. DCHECK(hid_connection_);
  91. hid_connection_->GetFeatureReport(
  92. report_id,
  93. base::BindOnce(&HidConnectionImpl::OnGetFeatureReport,
  94. weak_factory_.GetWeakPtr(), std::move(callback)));
  95. }
  96. void HidConnectionImpl::OnGetFeatureReport(
  97. GetFeatureReportCallback callback,
  98. bool success,
  99. scoped_refptr<base::RefCountedBytes> buffer,
  100. size_t size) {
  101. if (!success) {
  102. std::move(callback).Run(false, absl::nullopt);
  103. return;
  104. }
  105. DCHECK(buffer);
  106. std::vector<uint8_t> data(buffer->front(), buffer->front() + size);
  107. std::move(callback).Run(true, data);
  108. }
  109. void HidConnectionImpl::SendFeatureReport(uint8_t report_id,
  110. const std::vector<uint8_t>& buffer,
  111. SendFeatureReportCallback callback) {
  112. DCHECK(hid_connection_);
  113. auto io_buffer =
  114. base::MakeRefCounted<base::RefCountedBytes>(buffer.size() + 1);
  115. io_buffer->data()[0] = report_id;
  116. memcpy(io_buffer->front() + 1, buffer.data(), buffer.size());
  117. hid_connection_->SendFeatureReport(
  118. io_buffer,
  119. base::BindOnce(&HidConnectionImpl::OnSendFeatureReport,
  120. weak_factory_.GetWeakPtr(), std::move(callback)));
  121. }
  122. void HidConnectionImpl::OnSendFeatureReport(SendFeatureReportCallback callback,
  123. bool success) {
  124. std::move(callback).Run(success);
  125. }
  126. } // namespace device