Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(320)

Side by Side Diff: device/gamepad/xbox_data_fetcher_mac.mm

Issue 2129003002: Refactored gamepad polling to support dynamic sources (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Fixed unit test issue and Mac XBoxDataFetcher constructor Created 4 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Copyright 2013 The Chromium Authors. All rights reserved. 1 // Copyright 2013 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "device/gamepad/xbox_data_fetcher_mac.h" 5 #include "device/gamepad/xbox_data_fetcher_mac.h"
6 6
7 #include <algorithm> 7 #include <algorithm>
8 #include <cmath> 8 #include <cmath>
9 #include <limits> 9 #include <limits>
10 10
11 #include <CoreFoundation/CoreFoundation.h> 11 #include <CoreFoundation/CoreFoundation.h>
12 #include <IOKit/IOCFPlugIn.h> 12 #include <IOKit/IOCFPlugIn.h>
13 #include <IOKit/IOKitLib.h> 13 #include <IOKit/IOKitLib.h>
14 #include <IOKit/usb/IOUSBLib.h> 14 #include <IOKit/usb/IOUSBLib.h>
15 #include <IOKit/usb/USB.h> 15 #include <IOKit/usb/USB.h>
16 16
17 #include "base/logging.h" 17 #include "base/logging.h"
18 #include "base/mac/foundation_util.h" 18 #include "base/mac/foundation_util.h"
19 19
20 using blink::WebGamepad;
21
22 namespace device {
23
20 namespace { 24 namespace {
25
21 const int kVendorMicrosoft = 0x045e; 26 const int kVendorMicrosoft = 0x045e;
22 const int kProductXbox360Controller = 0x028e; 27 const int kProductXbox360Controller = 0x028e;
23 const int kProductXboxOneController = 0x02d1; 28 const int kProductXboxOneController = 0x02d1;
24 29
25 const int kXbox360ReadEndpoint = 1; 30 const int kXbox360ReadEndpoint = 1;
26 const int kXbox360ControlEndpoint = 2; 31 const int kXbox360ControlEndpoint = 2;
27 32
28 const int kXboxOneReadEndpoint = 2; 33 const int kXboxOneReadEndpoint = 2;
29 const int kXboxOneControlEndpoint = 1; 34 const int kXboxOneControlEndpoint = 1;
30 35
(...skipping 184 matching lines...) Expand 10 before | Expand all | Expand 10 after
215 normalized_data->buttons[13] = data.dpad_right; 220 normalized_data->buttons[13] = data.dpad_right;
216 normalized_data->buttons[14] = data.sync; 221 normalized_data->buttons[14] = data.sync;
217 normalized_data->triggers[0] = NormalizeXboxOneTrigger(data.trigger_left); 222 normalized_data->triggers[0] = NormalizeXboxOneTrigger(data.trigger_left);
218 normalized_data->triggers[1] = NormalizeXboxOneTrigger(data.trigger_right); 223 normalized_data->triggers[1] = NormalizeXboxOneTrigger(data.trigger_right);
219 NormalizeAxis(data.stick_left_x, data.stick_left_y, kLeftThumbDeadzone, 224 NormalizeAxis(data.stick_left_x, data.stick_left_y, kLeftThumbDeadzone,
220 &normalized_data->axes[0], &normalized_data->axes[1]); 225 &normalized_data->axes[0], &normalized_data->axes[1]);
221 NormalizeAxis(data.stick_right_x, data.stick_right_y, kRightThumbDeadzone, 226 NormalizeAxis(data.stick_right_x, data.stick_right_y, kRightThumbDeadzone,
222 &normalized_data->axes[2], &normalized_data->axes[3]); 227 &normalized_data->axes[2], &normalized_data->axes[3]);
223 } 228 }
224 229
230 void CopyNSStringAsUTF16LittleEndian(NSString* src,
231 blink::WebUChar* dest,
232 size_t dest_len) {
233 NSData* as16 = [src dataUsingEncoding:NSUTF16LittleEndianStringEncoding];
234 memset(dest, 0, dest_len);
235 [as16 getBytes:dest length:dest_len - sizeof(blink::WebUChar)];
236 }
237
225 } // namespace 238 } // namespace
226 239
227 XboxController::XboxController(Delegate* delegate) 240 XboxController::XboxController(Delegate* delegate)
228 : device_(NULL), 241 : device_(NULL),
229 interface_(NULL), 242 interface_(NULL),
230 device_is_open_(false), 243 device_is_open_(false),
231 interface_is_open_(false), 244 interface_is_open_(false),
232 read_buffer_size_(0), 245 read_buffer_size_(0),
233 led_pattern_(LED_NUM_PATTERNS), 246 led_pattern_(LED_NUM_PATTERNS),
234 location_id_(0), 247 location_id_(0),
(...skipping 353 matching lines...) Expand 10 before | Expand all | Expand 10 after
588 (UInt32)length, WriteComplete, buffer); 601 (UInt32)length, WriteComplete, buffer);
589 if (kr != KERN_SUCCESS) { 602 if (kr != KERN_SUCCESS) {
590 delete[] buffer; 603 delete[] buffer;
591 IOError(); 604 IOError();
592 return; 605 return;
593 } 606 }
594 } 607 }
595 608
596 //----------------------------------------------------------------------------- 609 //-----------------------------------------------------------------------------
597 610
598 XboxDataFetcher::XboxDataFetcher(Delegate* delegate) 611 XboxDataFetcher::XboxDataFetcher()
599 : delegate_(delegate), listening_(false), source_(NULL), port_(NULL) {} 612 : listening_(false), source_(NULL), port_(NULL) {}
600 613
601 XboxDataFetcher::~XboxDataFetcher() { 614 XboxDataFetcher::~XboxDataFetcher() {
602 while (!controllers_.empty()) { 615 while (!controllers_.empty()) {
603 RemoveController(*controllers_.begin()); 616 RemoveController(*controllers_.begin());
604 } 617 }
605 UnregisterFromNotifications(); 618 UnregisterFromNotifications();
606 } 619 }
607 620
621 GamepadSource XboxDataFetcher::source() {
622 return Factory::static_source();
623 }
624
625 void XboxDataFetcher::GetGamepadData(bool devices_changed_hint) {
626 // This just loops through all the connected pads and "pings" them to indicate
627 // that they're still active.
628 for (const auto& controller : controllers_) {
629 GetPadState(controller->location_id());
630 }
631 }
632
633 void XboxDataFetcher::OnAddedToProvider() {
634 RegisterForNotifications();
635 }
636
608 void XboxDataFetcher::DeviceAdded(void* context, io_iterator_t iterator) { 637 void XboxDataFetcher::DeviceAdded(void* context, io_iterator_t iterator) {
609 DCHECK(context); 638 DCHECK(context);
610 XboxDataFetcher* fetcher = static_cast<XboxDataFetcher*>(context); 639 XboxDataFetcher* fetcher = static_cast<XboxDataFetcher*>(context);
611 io_service_t ref; 640 io_service_t ref;
612 while ((ref = IOIteratorNext(iterator))) { 641 while ((ref = IOIteratorNext(iterator))) {
613 base::mac::ScopedIOObject<io_service_t> scoped_ref(ref); 642 base::mac::ScopedIOObject<io_service_t> scoped_ref(ref);
614 XboxController* controller = new XboxController(fetcher); 643 XboxController* controller = new XboxController(fetcher);
615 if (controller->OpenDevice(ref)) { 644 if (controller->OpenDevice(ref)) {
616 fetcher->AddController(controller); 645 fetcher->AddController(controller);
617 } else { 646 } else {
(...skipping 107 matching lines...) Expand 10 before | Expand all | Expand 10 after
725 if ((*i)->location_id() == location_id) 754 if ((*i)->location_id() == location_id)
726 return *i; 755 return *i;
727 } 756 }
728 return NULL; 757 return NULL;
729 } 758 }
730 759
731 void XboxDataFetcher::AddController(XboxController* controller) { 760 void XboxDataFetcher::AddController(XboxController* controller) {
732 DCHECK(!ControllerForLocation(controller->location_id())) 761 DCHECK(!ControllerForLocation(controller->location_id()))
733 << "Controller with location ID " << controller->location_id() 762 << "Controller with location ID " << controller->location_id()
734 << " already exists in the set of controllers."; 763 << " already exists in the set of controllers.";
764 PadState* state = GetPadState(controller->location_id());
765 if (!state) {
766 delete controller;
767 return; // No available slot for this device
768 }
769
735 controllers_.insert(controller); 770 controllers_.insert(controller);
736 delegate_->XboxDeviceAdd(controller); 771
772 controller->SetLEDPattern((XboxController::LEDPattern)(
773 XboxController::LED_FLASH_TOP_LEFT + controller->location_id()));
774
775 NSString* ident = [NSString
776 stringWithFormat:@"%@ (STANDARD GAMEPAD Vendor: %04x Product: %04x)",
777 controller->GetControllerType() ==
778 XboxController::XBOX_360_CONTROLLER
779 ? @"Xbox 360 Controller"
780 : @"Xbox One Controller",
781 controller->GetProductId(), controller->GetVendorId()];
782 CopyNSStringAsUTF16LittleEndian(ident, state->data.id,
783 sizeof(state->data.id));
784
785 CopyNSStringAsUTF16LittleEndian(@"standard", state->data.mapping,
786 sizeof(state->data.mapping));
787
788 state->data.connected = true;
789 state->data.axesLength = 4;
790 state->data.buttonsLength = 17;
791 state->data.timestamp = 0;
792 state->mapper = 0;
793 state->axis_mask = 0;
794 state->button_mask = 0;
737 } 795 }
738 796
739 void XboxDataFetcher::RemoveController(XboxController* controller) { 797 void XboxDataFetcher::RemoveController(XboxController* controller) {
740 delegate_->XboxDeviceRemove(controller);
741 controllers_.erase(controller); 798 controllers_.erase(controller);
742 delete controller; 799 delete controller;
743 } 800 }
744 801
745 void XboxDataFetcher::RemoveControllerByLocationID(uint32_t location_id) { 802 void XboxDataFetcher::RemoveControllerByLocationID(uint32_t location_id) {
746 XboxController* controller = NULL; 803 XboxController* controller = NULL;
747 for (std::set<XboxController*>::iterator i = controllers_.begin(); 804 for (std::set<XboxController*>::iterator i = controllers_.begin();
748 i != controllers_.end(); ++i) { 805 i != controllers_.end(); ++i) {
749 if ((*i)->location_id() == location_id) { 806 if ((*i)->location_id() == location_id) {
750 controller = *i; 807 controller = *i;
751 break; 808 break;
752 } 809 }
753 } 810 }
754 if (controller) 811 if (controller)
755 RemoveController(controller); 812 RemoveController(controller);
756 } 813 }
757 814
758 void XboxDataFetcher::XboxControllerGotData(XboxController* controller, 815 void XboxDataFetcher::XboxControllerGotData(XboxController* controller,
759 const XboxController::Data& data) { 816 const XboxController::Data& data) {
760 delegate_->XboxValueChanged(controller, data); 817 PadState* state = GetPadState(controller->location_id());
818 if (!state)
819 return; // No available slot for this device
820
821 WebGamepad& pad = state->data;
822
823 for (size_t i = 0; i < 6; i++) {
824 pad.buttons[i].pressed = data.buttons[i];
825 pad.buttons[i].value = data.buttons[i] ? 1.0f : 0.0f;
826 }
827 pad.buttons[6].pressed = data.triggers[0] > kDefaultButtonPressedThreshold;
828 pad.buttons[6].value = data.triggers[0];
829 pad.buttons[7].pressed = data.triggers[1] > kDefaultButtonPressedThreshold;
830 pad.buttons[7].value = data.triggers[1];
831 for (size_t i = 8; i < 17; i++) {
832 pad.buttons[i].pressed = data.buttons[i - 2];
833 pad.buttons[i].value = data.buttons[i - 2] ? 1.0f : 0.0f;
834 }
835 for (size_t i = 0; i < arraysize(data.axes); i++) {
836 pad.axes[i] = data.axes[i];
837 }
838
839 pad.timestamp = base::TimeTicks::Now().ToInternalValue();
761 } 840 }
762 841
763 void XboxDataFetcher::XboxControllerError(XboxController* controller) { 842 void XboxDataFetcher::XboxControllerError(XboxController* controller) {
764 RemoveController(controller); 843 RemoveController(controller);
765 } 844 }
845
846 } // namespace device
OLDNEW
« device/gamepad/gamepad_provider_unittest.cc ('K') | « device/gamepad/xbox_data_fetcher_mac.cc ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698