Upstream version 9.38.198.0
[platform/framework/web/crosswalk.git] / src / device / hid / hid_connection_mac.cc
index 63b7998..b357216 100644 (file)
@@ -7,7 +7,6 @@
 #include "base/bind.h"
 #include "base/mac/foundation_util.h"
 #include "base/message_loop/message_loop.h"
-#include "base/threading/thread_restrictions.h"
 #include "device/hid/hid_connection_mac.h"
 
 namespace device {
@@ -15,85 +14,74 @@ namespace device {
 HidConnectionMac::HidConnectionMac(HidDeviceInfo device_info)
     : HidConnection(device_info),
       device_(device_info.device_id, base::scoped_policy::RETAIN) {
-  DCHECK(thread_checker_.CalledOnValidThread());
-
   message_loop_ = base::MessageLoopProxy::current();
 
   DCHECK(device_.get());
-  inbound_buffer_.reset((uint8_t*)malloc(device_info.input_report_size));
+  size_t expected_report_size = device_info.max_input_report_size;
+  if (device_info.has_report_id) {
+    expected_report_size++;
+  }
+  inbound_buffer_.reset((uint8_t*)malloc(expected_report_size));
   IOHIDDeviceRegisterInputReportCallback(device_.get(),
                                          inbound_buffer_.get(),
-                                         device_info.input_report_size,
+                                         expected_report_size,
                                          &HidConnectionMac::InputReportCallback,
                                          this);
   IOHIDDeviceOpen(device_, kIOHIDOptionsTypeNone);
 }
 
 HidConnectionMac::~HidConnectionMac() {
-  DCHECK(thread_checker_.CalledOnValidThread());
-
-  while (!pending_reads_.empty()) {
-    pending_reads_.front().callback.Run(false, 0);
-    pending_reads_.pop();
-  }
-
   IOHIDDeviceClose(device_, kIOHIDOptionsTypeNone);
+  Flush();
 }
 
-void HidConnectionMac::Read(scoped_refptr<net::IOBufferWithSize> buffer,
-                            const IOCallback& callback) {
-  DCHECK(thread_checker_.CalledOnValidThread());
+void HidConnectionMac::PlatformRead(scoped_refptr<net::IOBufferWithSize> buffer,
+                                    const IOCallback& callback) {
   if (!device_) {
     callback.Run(false, 0);
     return;
   }
-  PendingHidRead read;
-  read.buffer = buffer;
-  read.callback = callback;
-  pending_reads_.push(read);
+
+  PendingHidRead pending_read;
+  pending_read.buffer = buffer;
+  pending_read.callback = callback;
+  pending_reads_.push(pending_read);
   ProcessReadQueue();
 }
 
-void HidConnectionMac::Write(uint8_t report_id,
-                             scoped_refptr<net::IOBufferWithSize> buffer,
-                             const IOCallback& callback) {
-  DCHECK(thread_checker_.CalledOnValidThread());
+void HidConnectionMac::PlatformWrite(
+    uint8_t report_id,
+    scoped_refptr<net::IOBufferWithSize> buffer,
+    const IOCallback& callback) {
   WriteReport(kIOHIDReportTypeOutput, report_id, buffer, callback);
 }
 
-void HidConnectionMac::GetFeatureReport(
+void HidConnectionMac::PlatformGetFeatureReport(
     uint8_t report_id,
     scoped_refptr<net::IOBufferWithSize> buffer,
     const IOCallback& callback) {
-  DCHECK(thread_checker_.CalledOnValidThread());
-  if (device_info().feature_report_size == 0) {
-    callback.Run(false, 0);
-    return;
-  }
-
-  if (buffer->size() < device_info().feature_report_size) {
+  if (!device_) {
     callback.Run(false, 0);
     return;
   }
 
   uint8_t* feature_report_buffer = reinterpret_cast<uint8_t*>(buffer->data());
-  CFIndex feature_report_size = device_info().feature_report_size;
+  CFIndex report_size = buffer->size();
   IOReturn result = IOHIDDeviceGetReport(device_,
                                          kIOHIDReportTypeFeature,
                                          report_id,
                                          feature_report_buffer,
-                                         &feature_report_size);
+                                         &report_size);
   if (result == kIOReturnSuccess)
-    callback.Run(true, feature_report_size);
+    callback.Run(true, report_size);
   else
     callback.Run(false, 0);
 }
 
-void HidConnectionMac::SendFeatureReport(
+void HidConnectionMac::PlatformSendFeatureReport(
     uint8_t report_id,
     scoped_refptr<net::IOBufferWithSize> buffer,
     const IOCallback& callback) {
-  DCHECK(thread_checker_.CalledOnValidThread());
   WriteReport(kIOHIDReportTypeFeature, report_id, buffer, callback);
 }
 
@@ -105,69 +93,80 @@ void HidConnectionMac::InputReportCallback(void* context,
                                            uint8_t* report_bytes,
                                            CFIndex report_length) {
   HidConnectionMac* connection = static_cast<HidConnectionMac*>(context);
-  // If a report ID was received, inject it into a copy of the received
-  // report. This is consistent with how input reports are received on
-  // other platforms.
+  // report_id is already contained in report_bytes
   scoped_refptr<net::IOBufferWithSize> buffer;
-  if (report_id != 0) {
-    buffer = new net::IOBufferWithSize(report_length + 1);
-    buffer->data()[0] = static_cast<uint8_t>(report_id);
-    memcpy(buffer->data() + 1, report_bytes, report_length);
-  } else {
-    buffer = new net::IOBufferWithSize(report_length);
-    memcpy(buffer->data(), report_bytes, report_length);
-  }
+  buffer = new net::IOBufferWithSize(report_length);
+  memcpy(buffer->data(), report_bytes, report_length);
+
   connection->message_loop_->PostTask(
       FROM_HERE,
-      base::Bind(
-          &HidConnectionMac::ProcessInputReport, connection, type, buffer));
-}
-
-void HidConnectionMac::ProcessReadQueue() {
-  DCHECK(thread_checker_.CalledOnValidThread());
-  while (pending_reads_.size() && pending_reports_.size()) {
-    PendingHidRead read = pending_reads_.front();
-    pending_reads_.pop();
-    PendingHidReport report = pending_reports_.front();
-    if (read.buffer->size() < report.buffer->size()) {
-      read.callback.Run(false, report.buffer->size());
-    } else {
-      memcpy(read.buffer->data(), report.buffer->data(), report.buffer->size());
-      pending_reports_.pop();
-      read.callback.Run(true, report.buffer->size());
-    }
-  }
-}
-
-void HidConnectionMac::ProcessInputReport(
-    IOHIDReportType type,
-    scoped_refptr<net::IOBufferWithSize> buffer) {
-  DCHECK(thread_checker_.CalledOnValidThread());
-  PendingHidReport report;
-  report.buffer = buffer;
-  pending_reports_.push(report);
-  ProcessReadQueue();
+      base::Bind(&HidConnectionMac::ProcessInputReport, connection, buffer));
 }
 
 void HidConnectionMac::WriteReport(IOHIDReportType type,
                                    uint8_t report_id,
                                    scoped_refptr<net::IOBufferWithSize> buffer,
                                    const IOCallback& callback) {
-  DCHECK(thread_checker_.CalledOnValidThread());
   if (!device_) {
     callback.Run(false, 0);
     return;
   }
+
+  scoped_refptr<net::IOBufferWithSize> output_buffer;
+  if (report_id != 0) {
+    output_buffer = new net::IOBufferWithSize(buffer->size() + 1);
+    output_buffer->data()[0] = static_cast<uint8_t>(report_id);
+    memcpy(output_buffer->data() + 1, buffer->data(), buffer->size());
+  } else {
+    output_buffer = new net::IOBufferWithSize(buffer->size());
+    memcpy(output_buffer->data(), buffer->data(), buffer->size());
+  }
   IOReturn res =
       IOHIDDeviceSetReport(device_.get(),
                            type,
                            report_id,
-                           reinterpret_cast<uint8_t*>(buffer->data()),
-                           buffer->size());
+                           reinterpret_cast<uint8_t*>(output_buffer->data()),
+                           output_buffer->size());
   if (res != kIOReturnSuccess) {
     callback.Run(false, 0);
   } else {
-    callback.Run(true, buffer->size());
+    callback.Run(true, output_buffer->size());
+  }
+}
+
+void HidConnectionMac::Flush() {
+  while (!pending_reads_.empty()) {
+    pending_reads_.front().callback.Run(false, 0);
+    pending_reads_.pop();
+  }
+}
+
+void HidConnectionMac::ProcessInputReport(
+    scoped_refptr<net::IOBufferWithSize> buffer) {
+  DCHECK(thread_checker().CalledOnValidThread());
+  PendingHidReport report;
+  report.buffer = buffer;
+  pending_reports_.push(report);
+  ProcessReadQueue();
+}
+
+void HidConnectionMac::ProcessReadQueue() {
+  DCHECK(thread_checker().CalledOnValidThread());
+  while (pending_reads_.size() && pending_reports_.size()) {
+    PendingHidRead read = pending_reads_.front();
+    PendingHidReport report = pending_reports_.front();
+
+    if (read.buffer->size() < report.buffer->size()) {
+      read.callback.Run(false, 0);
+      pending_reads_.pop();
+    } else {
+      memcpy(read.buffer->data(), report.buffer->data(), report.buffer->size());
+      pending_reports_.pop();
+
+      if (CompleteRead(read.buffer, report.buffer->size(), read.callback)) {
+        pending_reads_.pop();
+      }
+    }
   }
 }