Changeset 265079 in webkit
- Timestamp:
- Jul 30, 2020 12:21:44 AM (4 years ago)
- Location:
- trunk
- Files:
-
- 3 added
- 24 edited
- 6 copied
Legend:
- Unmodified
- Added
- Removed
-
trunk/Source/WebCore/ChangeLog
r265075 r265079 1 2020-07-30 Brady Eidson <beidson@apple.com> 2 3 Refactor HID gamepad code to be much less fragile and much easier to hack on. 4 https://bugs.webkit.org/show_bug.cgi?id=214910 5 6 Reviewed by Darin Adler. 7 8 Covered by API tests. 9 10 Currently - for HID device gamepads - we throw all buttons and axes against the wall and see what sticks. 11 Instead, for specific popular devices, we'd like to have device-specific mappings so the representation makes sense. 12 13 To support that work, this is a major refactoring of the HID gamepad code. It does the following: 14 15 - Breaks out logic specific to IOHIDDeviceRef into HIDDevice 16 17 - Breaks out logic specific to IOHIDElementRef into HIDElement 18 19 - Moves responsibities of managing things to the right places (e.g. HIDElement manages its own current value directly) 20 21 - Makes HIDGamepadElement derive from HIDElement directly 22 23 - Moves device specific logic from HIDGamepad into a subclass of HID gamepad. Currently the only subclass is "generic" 24 which encompasses HIDGamepad's old behavior 25 26 - Changes button/value vectors from Vector<double> to Vector<SharedGamepadValue> so multiple objects can reference 27 the value at once. 28 e.g. HIDGamepadButton can simply update it's own SharedGamepadValue without knowing which HIDGamepad owns it or which index 29 into the gamepad's value vector it should be mutating. 30 31 This will be critical in the "specific device mapping" work as some types of HIDElements actually drive more than one 32 gamepad button value. 33 e.g. a "direction pad axis" actually manages 2 button values, or a "hat-switch" direction pad manages 4 button values 34 35 This patch doesn't change any current behavior. 36 37 * Modules/gamepad/Gamepad.cpp: 38 (WebCore::Gamepad::updateFromPlatformGamepad): 39 40 * Sources.txt: 41 * SourcesCocoa.txt: 42 * WebCore.xcodeproj/project.pbxproj: 43 44 * platform/Logging.h: 45 46 * platform/gamepad/PlatformGamepad.h: 47 48 * platform/gamepad/SharedGamepadValue.h: Copied from Source/WebKit/UIProcess/Gamepad/UIGamepad.h. 49 (WebCore::SharedGamepadValue::SharedGamepadValue): 50 (WebCore::SharedGamepadValue::setValue): 51 (WebCore::SharedGamepadValue::value const): 52 (WebCore::SharedGamepadValue::Data::Data): 53 54 * platform/gamepad/cocoa/GameControllerGamepad.h: 55 * platform/gamepad/cocoa/GameControllerGamepad.mm: 56 (WebCore::GameControllerGamepad::setupAsExtendedGamepad): 57 (WebCore::GameControllerGamepad::setupAsGamepad): 58 59 * platform/gamepad/mac/GenericHIDGamepad.cpp: Added. 60 (WebCore::GenericHIDGamepad::GenericHIDGamepad): 61 (WebCore::GenericHIDGamepad::id): 62 (WebCore::GenericHIDGamepad::maybeAddGenericDesktopElement): 63 (WebCore::GenericHIDGamepad::maybeAddButtonElement): 64 * platform/gamepad/mac/GenericHIDGamepad.h: Copied from Source/WebKit/WebProcess/Gamepad/WebGamepad.h. 65 66 * platform/gamepad/mac/HIDGamepad.cpp: 67 (WebCore::HIDGamepad::create): 68 (WebCore::HIDGamepad::HIDGamepad): 69 (WebCore::HIDGamepad::initialize): 70 (WebCore::HIDGamepad::valueChanged): 71 (WebCore::HIDGamepad::getCurrentValueForElement): Deleted. 72 (WebCore::HIDGamepad::initElements): Deleted. 73 (WebCore::HIDGamepad::initElementsFromArray): Deleted. 74 (WebCore::HIDGamepad::maybeAddButton): Deleted. 75 (WebCore::HIDGamepad::maybeAddAxis): Deleted. 76 * platform/gamepad/mac/HIDGamepad.h: 77 (WebCore::HIDGamepad::hidDevice const): 78 (WebCore::HIDGamepadElement::HIDGamepadElement): Deleted. 79 (WebCore::HIDGamepadElement::~HIDGamepadElement): Deleted. 80 (WebCore::HIDGamepadElement::isButton const): Deleted. 81 (WebCore::HIDGamepadElement::isAxis const): Deleted. 82 (WebCore::HIDGamepadButton::HIDGamepadButton): Deleted. 83 (WebCore::HIDGamepadAxis::HIDGamepadAxis): Deleted. 84 85 * platform/gamepad/mac/HIDGamepadElement.cpp: Added. 86 (WebCore::HIDGamepadElement::HIDGamepadElement): 87 (WebCore::HIDGamepadElement::refreshCurrentValue): 88 (WebCore::HIDGamepadElement::normalizedValue): 89 (WebCore::HIDGamepadButton::gamepadValueChanged): 90 (WebCore::HIDGamepadAxis::gamepadValueChanged): 91 (WebCore::HIDGamepadAxis::normalizedValue): 92 * platform/gamepad/mac/HIDGamepadElement.h: Copied from Source/WebCore/platform/gamepad/PlatformGamepad.h. 93 (WebCore::HIDGamepadElement::~HIDGamepadElement): 94 (WebCore::HIDGamepadElement::isButton const): 95 (WebCore::HIDGamepadElement::isAxis const): 96 97 * platform/gamepad/mac/HIDGamepadProvider.mm: 98 (WebCore::HIDGamepadProvider::deviceAdded): 99 * platform/gamepad/mac/MultiGamepadProvider.h: 100 101 * platform/graphics/cocoa/SourceBufferParserWebM.cpp: 102 103 * platform/mac/HIDDevice.cpp: Added. 104 (WebCore::HIDDevice::HIDDevice): 105 (WebCore::HIDDevice::uniqueInputElementsInDeviceTreeOrder const): 106 * platform/mac/HIDDevice.h: Copied from Source/WebCore/platform/gamepad/PlatformGamepad.h. 107 (WebCore::HIDDevice::rawElement const): 108 (WebCore::HIDDevice::vendorID const): 109 (WebCore::HIDDevice::productID const): 110 (WebCore::HIDDevice::productName const): 111 112 * platform/mac/HIDElement.cpp: Copied from Source/WebKit/UIProcess/Gamepad/UIGamepad.h. 113 (WebCore::HIDElement::HIDElement): 114 (WebCore::HIDElement::valueChanged): 115 * platform/mac/HIDElement.h: Copied from Source/WebKit/UIProcess/Gamepad/UIGamepad.h. 116 (WebCore::HIDElement::rawElement const): 117 (WebCore::HIDElement::physicalMin const): 118 (WebCore::HIDElement::physicalMax const): 119 (WebCore::HIDElement::physicalValue const): 120 (WebCore::HIDElement::usage const): 121 (WebCore::HIDElement::usagePage const): 122 (WebCore::HIDElement::cookie const): 123 124 * testing/MockGamepad.cpp: 125 (WebCore::MockGamepad::updateDetails): 126 (WebCore::MockGamepad::setAxisValue): 127 (WebCore::MockGamepad::setButtonValue): 128 * testing/MockGamepad.h: 129 1 130 2020-07-29 Joonghun Park <jh718.park@samsung.com> 2 131 -
trunk/Source/WebCore/Modules/gamepad/Gamepad.cpp
r256215 r265079 63 63 { 64 64 for (unsigned i = 0; i < m_axes.size(); ++i) 65 m_axes[i] = platformGamepad.axisValues()[i] ;65 m_axes[i] = platformGamepad.axisValues()[i].value(); 66 66 for (unsigned i = 0; i < m_buttons.size(); ++i) 67 m_buttons[i]->setValue(platformGamepad.buttonValues()[i] );67 m_buttons[i]->setValue(platformGamepad.buttonValues()[i].value()); 68 68 69 69 m_timestamp = platformGamepad.lastUpdateTime(); -
trunk/Source/WebCore/Sources.txt
r265066 r265079 1816 1816 platform/encryptedmedia/CDMPrivate.cpp 1817 1817 platform/encryptedmedia/CDMProxy.cpp 1818 platform/gamepad/EmptyGamepadProvider.cpp 1819 platform/gamepad/GamepadProvider.cpp 1818 1820 platform/graphics/ANGLEWebKitBridge.cpp 1819 1821 platform/graphics/BitmapImage.cpp -
trunk/Source/WebCore/SourcesCocoa.txt
r264805 r265079 258 258 platform/gamepad/cocoa/GameControllerGamepad.mm 259 259 platform/gamepad/cocoa/GameControllerGamepadProvider.mm 260 platform/gamepad/mac/GenericHIDGamepad.cpp 260 261 platform/gamepad/mac/HIDGamepad.cpp 262 platform/gamepad/mac/HIDGamepadElement.cpp 261 263 platform/gamepad/mac/HIDGamepadProvider.mm 262 264 platform/gamepad/mac/MultiGamepadProvider.mm … … 469 471 platform/mac/BlocklistUpdater.mm 470 472 platform/mac/CursorMac.mm @no-unify 473 platform/mac/HIDDevice.cpp 474 platform/mac/HIDElement.cpp 471 475 platform/mac/KeyEventMac.mm @no-unify 472 476 platform/mac/LocalCurrentGraphicsContextMac.mm -
trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj
r265066 r265079 1399 1399 5106D7BE18BDB76F000AB166 /* ContextMenuContext.h in Headers */ = {isa = PBXBuildFile; fileRef = 5106D7BC18BDB76F000AB166 /* ContextMenuContext.h */; settings = {ATTRIBUTES = (Private, ); }; }; 1400 1400 510A58FA1BACC7F200C19282 /* IDBRequestData.h in Headers */ = {isa = PBXBuildFile; fileRef = 510A58F61BACC4A500C19282 /* IDBRequestData.h */; settings = {ATTRIBUTES = (Private, ); }; }; 1401 510A91DA24CF3D8C00BFD89C /* HIDGamepadElement.h in Headers */ = {isa = PBXBuildFile; fileRef = 510A91D624CE8EDE00BFD89C /* HIDGamepadElement.h */; settings = {ATTRIBUTES = (Private, ); }; }; 1402 510A91DC24CF46FE00BFD89C /* SharedGamepadValue.h in Headers */ = {isa = PBXBuildFile; fileRef = 510A91DB24CF441800BFD89C /* SharedGamepadValue.h */; settings = {ATTRIBUTES = (Private, ); }; }; 1403 510A91EA24D004C300BFD89C /* HIDElement.h in Headers */ = {isa = PBXBuildFile; fileRef = 510A91E324CFCC1800BFD89C /* HIDElement.h */; settings = {ATTRIBUTES = (Private, ); }; }; 1404 510A91EB24D004C800BFD89C /* HIDDevice.h in Headers */ = {isa = PBXBuildFile; fileRef = 510A91E224CFCC1800BFD89C /* HIDDevice.h */; settings = {ATTRIBUTES = (Private, ); }; }; 1401 1405 510D4A34103165EE0049EA54 /* SocketStreamError.h in Headers */ = {isa = PBXBuildFile; fileRef = 510D4A2E103165EE0049EA54 /* SocketStreamError.h */; settings = {ATTRIBUTES = (Private, ); }; }; 1402 1406 510D4A37103165EE0049EA54 /* SocketStreamHandle.h in Headers */ = {isa = PBXBuildFile; fileRef = 510D4A31103165EE0049EA54 /* SocketStreamHandle.h */; settings = {ATTRIBUTES = (Private, ); }; }; … … 1433 1437 514C767D0CE923A1007EF3CD /* ResourceRequestBase.h in Headers */ = {isa = PBXBuildFile; fileRef = 514C76680CE923A1007EF3CD /* ResourceRequestBase.h */; settings = {ATTRIBUTES = (Private, ); }; }; 1434 1438 514C767F0CE923A1007EF3CD /* ResourceResponseBase.h in Headers */ = {isa = PBXBuildFile; fileRef = 514C766A0CE923A1007EF3CD /* ResourceResponseBase.h */; settings = {ATTRIBUTES = (Private, ); }; }; 1435 515BE18F1D54F5FB00DD7C68 /* EmptyGamepadProvider.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 515BE1881D54F5F600DD7C68 /* EmptyGamepadProvider.cpp */; };1436 1439 515BE1901D54F5FB00DD7C68 /* EmptyGamepadProvider.h in Headers */ = {isa = PBXBuildFile; fileRef = 515BE1891D54F5F600DD7C68 /* EmptyGamepadProvider.h */; }; 1437 515BE1911D54F5FB00DD7C68 /* GamepadProvider.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 515BE18A1D54F5F600DD7C68 /* GamepadProvider.cpp */; };1438 1440 515BE1921D54F5FB00DD7C68 /* GamepadProvider.h in Headers */ = {isa = PBXBuildFile; fileRef = 515BE18B1D54F5F600DD7C68 /* GamepadProvider.h */; settings = {ATTRIBUTES = (Private, ); }; }; 1439 1441 515BE1931D54F5FB00DD7C68 /* GamepadProviderClient.h in Headers */ = {isa = PBXBuildFile; fileRef = 515BE18C1D54F5F600DD7C68 /* GamepadProviderClient.h */; settings = {ATTRIBUTES = (Private, ); }; }; … … 8215 8217 510A58FD1BB07A9600C19282 /* IDBConnectionToServer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = IDBConnectionToServer.h; sourceTree = "<group>"; }; 8216 8218 510A58FE1BB07AA500C19282 /* IDBConnectionToClient.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = IDBConnectionToClient.h; sourceTree = "<group>"; }; 8219 510A91D524CE8EDE00BFD89C /* HIDGamepadElement.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = HIDGamepadElement.cpp; sourceTree = "<group>"; }; 8220 510A91D624CE8EDE00BFD89C /* HIDGamepadElement.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = HIDGamepadElement.h; sourceTree = "<group>"; }; 8221 510A91DB24CF441800BFD89C /* SharedGamepadValue.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SharedGamepadValue.h; sourceTree = "<group>"; }; 8222 510A91E224CFCC1800BFD89C /* HIDDevice.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = HIDDevice.h; sourceTree = "<group>"; }; 8223 510A91E324CFCC1800BFD89C /* HIDElement.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = HIDElement.h; sourceTree = "<group>"; }; 8224 510A91E424CFCC1800BFD89C /* HIDElement.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = HIDElement.cpp; sourceTree = "<group>"; }; 8225 510A91E524CFCC1800BFD89C /* HIDDevice.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = HIDDevice.cpp; sourceTree = "<group>"; }; 8226 510A91E724CFEA1700BFD89C /* GenericHIDGamepad.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = GenericHIDGamepad.cpp; sourceTree = "<group>"; }; 8227 510A91E924CFEA3200BFD89C /* GenericHIDGamepad.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = GenericHIDGamepad.h; sourceTree = "<group>"; }; 8217 8228 510D4A2E103165EE0049EA54 /* SocketStreamError.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SocketStreamError.h; sourceTree = "<group>"; }; 8218 8229 510D4A30103165EE0049EA54 /* SocketStreamHandle.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = SocketStreamHandle.cpp; sourceTree = "<group>"; }; … … 8370 8381 51714EAE1CF6654A004723C4 /* JSGCObservation.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = JSGCObservation.cpp; sourceTree = "<group>"; }; 8371 8382 51714EAF1CF6654A004723C4 /* JSGCObservation.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JSGCObservation.h; sourceTree = "<group>"; }; 8383 51715FE824CD05DD002C97E6 /* GamepadConstants.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = GamepadConstants.cpp; sourceTree = "<group>"; }; 8384 51715FE924CD05DD002C97E6 /* GamepadConstants.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = GamepadConstants.h; sourceTree = "<group>"; }; 8372 8385 51741D0B0B07259A00ED442C /* BackForwardClient.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = BackForwardClient.h; sourceTree = "<group>"; }; 8373 8386 51741D0D0B07259A00ED442C /* HistoryItem.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = HistoryItem.h; sourceTree = "<group>"; }; … … 19644 19657 515BE1881D54F5F600DD7C68 /* EmptyGamepadProvider.cpp */, 19645 19658 515BE1891D54F5F600DD7C68 /* EmptyGamepadProvider.h */, 19659 51715FE824CD05DD002C97E6 /* GamepadConstants.cpp */, 19660 51715FE924CD05DD002C97E6 /* GamepadConstants.h */, 19646 19661 515BE18A1D54F5F600DD7C68 /* GamepadProvider.cpp */, 19647 19662 515BE18B1D54F5F600DD7C68 /* GamepadProvider.h */, 19648 19663 515BE18C1D54F5F600DD7C68 /* GamepadProviderClient.h */, 19649 19664 515BE18E1D54F5F600DD7C68 /* PlatformGamepad.h */, 19665 510A91DB24CF441800BFD89C /* SharedGamepadValue.h */, 19650 19666 ); 19651 19667 path = gamepad; … … 19655 19671 isa = PBXGroup; 19656 19672 children = ( 19673 510A91E724CFEA1700BFD89C /* GenericHIDGamepad.cpp */, 19674 510A91E924CFEA3200BFD89C /* GenericHIDGamepad.h */, 19657 19675 515BE1971D54F6BD00DD7C68 /* HIDGamepad.cpp */, 19658 19676 515BE1981D54F6BD00DD7C68 /* HIDGamepad.h */, 19677 510A91D524CE8EDE00BFD89C /* HIDGamepadElement.cpp */, 19678 510A91D624CE8EDE00BFD89C /* HIDGamepadElement.h */, 19659 19679 515BE19A1D54F6BD00DD7C68 /* HIDGamepadProvider.h */, 19660 19680 515BE1991D54F6BD00DD7C68 /* HIDGamepadProvider.mm */, … … 21052 21072 F58784F002DE375901EA4122 /* CursorMac.mm */, 21053 21073 E1BA66F01742BD8600C20251 /* DynamicLinkerInterposing.h */, 21074 510A91E524CFCC1800BFD89C /* HIDDevice.cpp */, 21075 510A91E224CFCC1800BFD89C /* HIDDevice.h */, 21076 510A91E424CFCC1800BFD89C /* HIDElement.cpp */, 21077 510A91E324CFCC1800BFD89C /* HIDElement.h */, 21054 21078 935C476E09AC4D7300A6AAB4 /* KeyEventMac.mm */, 21055 21079 F44A5F571FED3830007F5944 /* LegacyNSPasteboardTypes.h */, … … 31031 31055 CDA595982146DF7800A84185 /* HEVCUtilitiesCocoa.h in Headers */, 31032 31056 F55B3DC01251F12D003EF269 /* HiddenInputType.h in Headers */, 31057 510A91EB24D004C800BFD89C /* HIDDevice.h in Headers */, 31058 510A91EA24D004C300BFD89C /* HIDElement.h in Headers */, 31033 31059 515BE19C1D54F6C100DD7C68 /* HIDGamepad.h in Headers */, 31060 510A91DA24CF3D8C00BFD89C /* HIDGamepadElement.h in Headers */, 31034 31061 515BE19E1D54F6C100DD7C68 /* HIDGamepadProvider.h in Headers */, 31035 31062 CDCFABBD18C0AF78006F8450 /* HighlightData.h in Headers */, … … 33309 33336 1D9F0FC12122029B005D8FD4 /* ShareData.h in Headers */, 33310 33337 1A4A954E0B4EDCCB002D8C3C /* SharedBuffer.h in Headers */, 33338 510A91DC24CF46FE00BFD89C /* SharedGamepadValue.h in Headers */, 33311 33339 834DFAD01F7DAE5D00C2725B /* SharedStringHash.h in Headers */, 33312 33340 93309EA3099EB78C0056E581 /* SharedTimer.h in Headers */, … … 34619 34647 5CBD59592280E926002B22AA /* CustomHeaderFields.cpp in Sources */, 34620 34648 4463CF682212FA68001A8577 /* DataDetectorsCoreSoftLink.mm in Sources */, 34621 515BE18F1D54F5FB00DD7C68 /* EmptyGamepadProvider.cpp in Sources */,34622 34649 6E72F54C229DCD0C00B3E151 /* ExtensionsGLANGLE.cpp in Sources */, 34623 34650 7CE6CBFD187F394900D46BF5 /* FormatConverter.cpp in Sources */, … … 34627 34654 516C62201950D48700337E75 /* GamepadEvent.cpp in Sources */, 34628 34655 51A9D9E9195B931F001B2B5C /* GamepadManager.cpp in Sources */, 34629 515BE1911D54F5FB00DD7C68 /* GamepadProvider.cpp in Sources */,34630 34656 837964CF1F8DB69D00218EA0 /* GeolocationPositionDataIOS.mm in Sources */, 34631 34657 6E72F54E229DCD1000B3E151 /* GraphicsContextGLANGLE.cpp in Sources */, -
trunk/Source/WebCore/platform/Logging.h
r264134 r265079 1 1 /* 2 * Copyright (C) 2003-20 17Apple Inc. All rights reserved.2 * Copyright (C) 2003-2020 Apple Inc. All rights reserved. 3 3 * 4 4 * Redistribution and use in source and binary forms, with or without … … 64 64 M(Fullscreen) \ 65 65 M(Gamepad) \ 66 M(HID) \ 66 67 M(History) \ 67 68 M(IOSurface) \ -
trunk/Source/WebCore/platform/gamepad/PlatformGamepad.h
r264207 r265079 28 28 #if ENABLE(GAMEPAD) 29 29 30 #include "SharedGamepadValue.h" 30 31 #include <wtf/Forward.h> 31 32 #include <wtf/MonotonicTime.h> … … 44 45 virtual MonotonicTime lastUpdateTime() const { return m_lastUpdateTime; } 45 46 MonotonicTime connectTime() const { return m_connectTime; } 46 virtual const Vector<double>& axisValues() const = 0; 47 virtual const Vector<double>& buttonValues() const = 0; 47 48 virtual const Vector<SharedGamepadValue>& axisValues() const = 0; 49 virtual const Vector<SharedGamepadValue>& buttonValues() const = 0; 48 50 49 51 virtual const char* source() const { return "Unknown"_s; } -
trunk/Source/WebCore/platform/gamepad/SharedGamepadValue.h
r265078 r265079 1 1 /* 2 * Copyright (C) 20 16Apple Inc. All rights reserved.2 * Copyright (C) 2020 Apple Inc. All rights reserved. 3 3 * 4 4 * Redistribution and use in source and binary forms, with or without … … 28 28 #if ENABLE(GAMEPAD) 29 29 30 #include <wtf/MonotonicTime.h> 31 #include <wtf/Vector.h> 32 #include <wtf/text/WTFString.h> 30 #include <wtf/FastMalloc.h> 31 #include <wtf/Nonmovable.h> 32 #include <wtf/Ref.h> 33 #include <wtf/RefCounted.h> 33 34 34 35 namespace WebCore { 35 class PlatformGamepad;36 }37 36 38 namespace WebKit { 37 class SharedGamepadValue { 38 public: 39 SharedGamepadValue() 40 : m_data(adoptRef(*new Data(0.0))) 41 { 42 } 39 43 40 class GamepadData; 44 explicit SharedGamepadValue(double value) 45 : m_data(adoptRef(*new Data(value))) 46 { 47 } 41 48 42 class UIGamepad { 43 WTF_MAKE_FAST_ALLOCATED; 44 public: 45 UIGamepad(WebCore::PlatformGamepad&); 46 47 unsigned index() const { return m_index; } 48 49 GamepadData condensedGamepadData() const; 50 GamepadData fullGamepadData() const; 51 52 void updateFromPlatformGamepad(WebCore::PlatformGamepad&); 49 void setValue(double value) { m_data->value = value; } 50 double value() const { return m_data->value; } 53 51 54 52 private: 55 unsigned m_index; 56 String m_id; 57 String m_mapping; 58 Vector<double> m_axisValues; 59 Vector<double> m_buttonValues; 60 MonotonicTime m_lastUpdateTime; 53 struct Data : RefCounted<Data> { 54 WTF_MAKE_STRUCT_FAST_ALLOCATED; 55 56 Data(double theValue) 57 : value(theValue) 58 { 59 } 60 61 double value; 62 }; 63 64 Ref<Data> m_data; 61 65 }; 62 66 63 } 67 } // namespace WebCore 64 68 65 69 #endif // ENABLE(GAMEPAD) -
trunk/Source/WebCore/platform/gamepad/cocoa/GameControllerGamepad.h
r264207 r265079 45 45 GameControllerGamepad(GCController *, unsigned index); 46 46 47 const Vector< double>& axisValues() const final { return m_axisValues; }48 const Vector< double>& buttonValues() const final { return m_buttonValues; }47 const Vector<SharedGamepadValue>& axisValues() const final { return m_axisValues; } 48 const Vector<SharedGamepadValue>& buttonValues() const final { return m_buttonValues; } 49 49 50 50 const char* source() const final { return "GameController"_s; } … … 56 56 RetainPtr<GCController> m_gcController; 57 57 58 Vector< double> m_axisValues;59 Vector< double> m_buttonValues;58 Vector<SharedGamepadValue> m_axisValues; 59 Vector<SharedGamepadValue> m_buttonValues; 60 60 61 61 RetainPtr<GCGamepad> m_gamepad; -
trunk/Source/WebCore/platform/gamepad/cocoa/GameControllerGamepad.mm
r264258 r265079 111 111 112 112 auto bindButton = ^(GCControllerButtonInput *button, GamepadButtons index) { 113 m_buttonValues[(size_t)index] = button.value;113 m_buttonValues[(size_t)index].setValue(button.value); 114 114 button.valueChangedHandler = ^(GCControllerButtonInput *, float value, BOOL pressed) { 115 m_buttonValues[(size_t)index] = value;115 m_buttonValues[(size_t)index].setValue(value); 116 116 if (pressed) 117 117 m_hadButtonPresses = true; … … 159 159 160 160 m_axisValues.resize(4); 161 m_axisValues[0] = m_extendedGamepad.get().leftThumbstick.xAxis.value;162 m_axisValues[1] = -m_extendedGamepad.get().leftThumbstick.yAxis.value;163 m_axisValues[2] = m_extendedGamepad.get().rightThumbstick.xAxis.value;164 m_axisValues[3] = -m_extendedGamepad.get().rightThumbstick.yAxis.value;161 m_axisValues[0].setValue(m_extendedGamepad.get().leftThumbstick.xAxis.value); 162 m_axisValues[1].setValue(-m_extendedGamepad.get().leftThumbstick.yAxis.value); 163 m_axisValues[2].setValue(m_extendedGamepad.get().rightThumbstick.xAxis.value); 164 m_axisValues[3].setValue(-m_extendedGamepad.get().rightThumbstick.yAxis.value); 165 165 166 166 m_extendedGamepad.get().leftThumbstick.xAxis.valueChangedHandler = ^(GCControllerAxisInput *, float value) { 167 m_axisValues[0] = value;167 m_axisValues[0].setValue(value); 168 168 }; 169 169 m_extendedGamepad.get().leftThumbstick.yAxis.valueChangedHandler = ^(GCControllerAxisInput *, float value) { 170 m_axisValues[1] = -value;170 m_axisValues[1].setValue(-value); 171 171 }; 172 172 m_extendedGamepad.get().rightThumbstick.xAxis.valueChangedHandler = ^(GCControllerAxisInput *, float value) { 173 m_axisValues[2] = value;173 m_axisValues[2].setValue(value); 174 174 }; 175 175 m_extendedGamepad.get().rightThumbstick.yAxis.valueChangedHandler = ^(GCControllerAxisInput *, float value) { 176 m_axisValues[3] = -value;176 m_axisValues[3].setValue(-value); 177 177 }; 178 178 } … … 193 193 194 194 m_buttonValues.resize(6); 195 m_buttonValues[0] = m_extendedGamepad.get().buttonA.value;196 m_buttonValues[1] = m_extendedGamepad.get().buttonB.value;197 m_buttonValues[2] = m_extendedGamepad.get().buttonX.value;198 m_buttonValues[3] = m_extendedGamepad.get().buttonY.value;199 m_buttonValues[4] = m_extendedGamepad.get().leftShoulder.value;200 m_buttonValues[5] = m_extendedGamepad.get().rightShoulder.value;195 m_buttonValues[0].setValue(m_extendedGamepad.get().buttonA.value); 196 m_buttonValues[1].setValue(m_extendedGamepad.get().buttonB.value); 197 m_buttonValues[2].setValue(m_extendedGamepad.get().buttonX.value); 198 m_buttonValues[3].setValue(m_extendedGamepad.get().buttonY.value); 199 m_buttonValues[4].setValue(m_extendedGamepad.get().leftShoulder.value); 200 m_buttonValues[5].setValue(m_extendedGamepad.get().rightShoulder.value); 201 201 202 202 m_axisValues.resize(2); 203 m_axisValues[0] = m_extendedGamepad.get().dpad.xAxis.value;204 m_axisValues[1] = m_extendedGamepad.get().dpad.yAxis.value;203 m_axisValues[0].setValue(m_extendedGamepad.get().dpad.xAxis.value); 204 m_axisValues[1].setValue(m_extendedGamepad.get().dpad.yAxis.value); 205 205 206 206 m_extendedGamepad.get().buttonA.valueChangedHandler = ^(GCControllerButtonInput *, float value, BOOL pressed) { 207 m_buttonValues[0] = value;207 m_buttonValues[0].setValue(value); 208 208 if (pressed) 209 209 m_hadButtonPresses = true; 210 210 }; 211 211 m_extendedGamepad.get().buttonB.valueChangedHandler = ^(GCControllerButtonInput *, float value, BOOL pressed) { 212 m_buttonValues[1] = value;212 m_buttonValues[1].setValue(value); 213 213 if (pressed) 214 214 m_hadButtonPresses = true; 215 215 }; 216 216 m_extendedGamepad.get().buttonX.valueChangedHandler = ^(GCControllerButtonInput *, float value, BOOL pressed) { 217 m_buttonValues[2] = value;217 m_buttonValues[2].setValue(value); 218 218 if (pressed) 219 219 m_hadButtonPresses = true; 220 220 }; 221 221 m_extendedGamepad.get().buttonY.valueChangedHandler = ^(GCControllerButtonInput *, float value, BOOL pressed) { 222 m_buttonValues[3] = value;222 m_buttonValues[3].setValue(value); 223 223 if (pressed) 224 224 m_hadButtonPresses = true; 225 225 }; 226 226 m_extendedGamepad.get().leftShoulder.valueChangedHandler = ^(GCControllerButtonInput *, float value, BOOL pressed) { 227 m_buttonValues[4] = value;227 m_buttonValues[4].setValue(value); 228 228 if (pressed) 229 229 m_hadButtonPresses = true; 230 230 }; 231 231 m_extendedGamepad.get().rightShoulder.valueChangedHandler = ^(GCControllerButtonInput *, float value, BOOL pressed) { 232 m_buttonValues[5] = value;232 m_buttonValues[5].setValue(value); 233 233 if (pressed) 234 234 m_hadButtonPresses = true; … … 236 236 237 237 m_extendedGamepad.get().leftThumbstick.xAxis.valueChangedHandler = ^(GCControllerAxisInput *, float value) { 238 m_axisValues[0] = value;238 m_axisValues[0].setValue(value); 239 239 }; 240 240 m_extendedGamepad.get().leftThumbstick.yAxis.valueChangedHandler = ^(GCControllerAxisInput *, float value) { 241 m_axisValues[1] = value;241 m_axisValues[1].setValue(value); 242 242 }; 243 243 } -
trunk/Source/WebCore/platform/gamepad/mac/GenericHIDGamepad.h
r265078 r265079 1 1 /* 2 * Copyright (C) 20 16Apple Inc. All rights reserved.2 * Copyright (C) 2020 Apple Inc. All rights reserved. 3 3 * 4 4 * Redistribution and use in source and binary forms, with or without … … 26 26 #pragma once 27 27 28 #if ENABLE(GAMEPAD) 28 #if ENABLE(GAMEPAD) && PLATFORM(MAC) 29 29 30 #include <WebCore/PlatformGamepad.h>30 #include "HIDGamepad.h" 31 31 32 namespace Web Kit{32 namespace WebCore { 33 33 34 class SharedMemory; 35 36 class GamepadData; 37 38 class WebGamepad : public WebCore::PlatformGamepad { 34 class GenericHIDGamepad final : public HIDGamepad { 39 35 public: 40 WebGamepad(const GamepadData&); 41 42 const Vector<double>& axisValues() const override; 43 const Vector<double>& buttonValues() const override; 44 45 void updateValues(const GamepadData&); 36 GenericHIDGamepad(HIDDevice&&, unsigned index); 46 37 47 38 private: 48 Vector<double> m_axisValues; 49 Vector<double> m_buttonValues; 39 String id() final; 40 41 void maybeAddGenericDesktopElement(HIDElement&); 42 void maybeAddButtonElement(HIDElement&); 50 43 }; 51 44 52 } 45 } // namespace WebCore 53 46 54 #endif // ENABLE(GAMEPAD) 47 #endif // ENABLE(GAMEPAD) && PLATFORM(MAC) -
trunk/Source/WebCore/platform/gamepad/mac/HIDGamepad.cpp
r264475 r265079 29 29 #if ENABLE(GAMEPAD) && PLATFORM(MAC) 30 30 31 #include "GenericHIDGamepad.h" 32 #include "Logging.h" 31 33 #include <IOKit/hid/IOHIDElement.h> 32 34 #include <IOKit/hid/IOHIDUsageTables.h> 33 35 #include <IOKit/hid/IOHIDValue.h> 34 #include <wtf/HexNumber.h>35 36 #include <wtf/cf/TypeCastsCF.h> 36 37 #include <wtf/text/CString.h> 37 38 38 WTF_DECLARE_CF_TYPE_TRAIT(IOHIDElement);39 40 39 namespace WebCore { 41 40 42 HIDGamepad::HIDGamepad(IOHIDDeviceRef hidDevice, unsigned index) 41 std::unique_ptr<HIDGamepad> HIDGamepad::create(IOHIDDeviceRef rawDevice, unsigned index) 42 { 43 auto device = HIDDevice { rawDevice }; 44 45 // When we support specific mapping for a particular device, here is where we'll decide what kind of HIDGamepad to make. 46 // For now, it's only the GenericHIDGamepad 47 auto newGamepad = makeUnique<GenericHIDGamepad>(WTFMove(device), index); 48 49 newGamepad->initialize(); 50 return WTFMove(newGamepad); 51 } 52 53 HIDGamepad::HIDGamepad(HIDDevice&& device, unsigned index) 43 54 : PlatformGamepad(index) 44 , m_ hidDevice(hidDevice)55 , m_device(WTFMove(device)) 45 56 { 46 57 m_connectTime = m_lastUpdateTime = MonotonicTime::now(); 47 48 CFNumberRef cfVendorID = (CFNumberRef)IOHIDDeviceGetProperty(hidDevice, CFSTR(kIOHIDVendorIDKey));49 CFNumberRef cfProductID = (CFNumberRef)IOHIDDeviceGetProperty(hidDevice, CFSTR(kIOHIDProductIDKey));50 51 int vendorID, productID;52 CFNumberGetValue(cfVendorID, kCFNumberIntType, &vendorID);53 CFNumberGetValue(cfProductID, kCFNumberIntType, &productID);54 55 CFStringRef cfProductName = (CFStringRef)IOHIDDeviceGetProperty(hidDevice, CFSTR(kIOHIDProductKey));56 String productName(cfProductName);57 58 // Currently the spec has no formatting for the id string.59 // This string formatting matches Firefox.60 m_id = makeString(hex(vendorID, Lowercase), '-', hex(productID, Lowercase), '-', productName);61 62 initElements();63 58 } 64 59 65 void HIDGamepad:: getCurrentValueForElement(const HIDGamepadElement& gamepadElement)60 void HIDGamepad::initialize() 66 61 { 67 IOHIDElementRef element = gamepadElement.iohidElement.get(); 68 IOHIDValueRef value; 69 if (IOHIDDeviceGetValue(IOHIDElementGetDevice(element), element, &value) == kIOReturnSuccess) 70 valueChanged(value); 71 } 62 m_id = id(); 72 63 73 void HIDGamepad::initElements() 74 { 75 RetainPtr<CFArrayRef> elements = adoptCF(IOHIDDeviceCopyMatchingElements(m_hidDevice.get(), NULL, kIOHIDOptionsTypeNone)); 76 initElementsFromArray(elements.get()); 77 78 // Buttons are specified to appear highest priority first in the array. 79 std::sort(m_buttons.begin(), m_buttons.end(), [](auto& a, auto& b) { 80 return a->priority < b->priority; 81 }); 82 83 LOG(Gamepad, "HIDGamepad initialized with %zu buttons and %zu axes", m_buttons.size(), m_axes.size()); 84 85 m_axisValues.resize(m_axes.size()); 86 m_buttonValues.resize(m_buttons.size()); 87 88 for (auto& button : m_buttons) 89 getCurrentValueForElement(button.get()); 90 91 for (auto& axis : m_axes) 92 getCurrentValueForElement(axis.get()); 93 } 94 95 void HIDGamepad::initElementsFromArray(CFArrayRef elements) 96 { 97 for (CFIndex i = 0, count = CFArrayGetCount(elements); i < count; ++i) { 98 IOHIDElementRef element = checked_cf_cast<IOHIDElementRef>(CFArrayGetValueAtIndex(elements, i)); 99 if (CFGetTypeID(element) != IOHIDElementGetTypeID()) 100 continue; 101 102 // As a physical element can appear in the device twice (in different collections) and can be 103 // represented by different IOHIDElementRef objects, we look at the IOHIDElementCookie which 104 // is meant to be unique for each physical element. 105 IOHIDElementCookie cookie = IOHIDElementGetCookie(element); 106 if (m_elementMap.contains(cookie)) 107 continue; 108 109 IOHIDElementType type = IOHIDElementGetType(element); 110 111 if ((type == kIOHIDElementTypeInput_Misc || type == kIOHIDElementTypeInput_Button)) { 112 if (maybeAddButton(element)) 113 continue; 114 } 115 116 if ((type == kIOHIDElementTypeInput_Misc || type == kIOHIDElementTypeInput_Axis) && maybeAddAxis(element)) 117 continue; 118 119 if (type == kIOHIDElementTypeCollection) 120 initElementsFromArray(IOHIDElementGetChildren(element)); 121 } 122 } 123 124 bool HIDGamepad::maybeAddButton(IOHIDElementRef element) 125 { 126 uint32_t usagePage = IOHIDElementGetUsagePage(element); 127 if (usagePage != kHIDPage_Button && usagePage != kHIDPage_GenericDesktop) 128 return false; 129 130 uint32_t usage = IOHIDElementGetUsage(element); 131 132 if (usagePage == kHIDPage_GenericDesktop) { 133 if (usage < kHIDUsage_GD_DPadUp || usage > kHIDUsage_GD_DPadLeft) 134 return false; 135 usage = std::numeric_limits<uint32_t>::max(); 136 } else if (!usage) 137 return false; 138 139 CFIndex min = IOHIDElementGetLogicalMin(element); 140 CFIndex max = IOHIDElementGetLogicalMax(element); 141 142 m_buttons.append(makeUniqueRef<HIDGamepadButton>(usage, min, max, element)); 143 144 IOHIDElementCookie cookie = IOHIDElementGetCookie(element); 145 m_elementMap.set(cookie, &m_buttons.last().get()); 146 147 return true; 148 } 149 150 bool HIDGamepad::maybeAddAxis(IOHIDElementRef element) 151 { 152 uint32_t usagePage = IOHIDElementGetUsagePage(element); 153 if (usagePage != kHIDPage_GenericDesktop) 154 return false; 155 156 uint32_t usage = IOHIDElementGetUsage(element); 157 // This range covers the standard axis usages. 158 if (usage < kHIDUsage_GD_X || usage > kHIDUsage_GD_Rz) 159 return false; 160 161 CFIndex min = IOHIDElementGetPhysicalMin(element); 162 CFIndex max = IOHIDElementGetPhysicalMax(element); 163 164 m_axes.append(makeUniqueRef<HIDGamepadAxis>(min, max, element)); 165 166 IOHIDElementCookie cookie = IOHIDElementGetCookie(element); 167 m_elementMap.set(cookie, &m_axes.last().get()); 168 169 return true; 64 for (auto& element : m_elementMap.values()) 65 element->refreshCurrentValue(); 170 66 } 171 67 … … 179 75 return HIDInputType::NotAButtonPress; 180 76 181 element->rawValue = IOHIDValueGetScaledValue(value, kIOHIDValueScaleTypePhysical);182 183 if (element->isButton()) {184 for (unsigned i = 0; i < m_buttons.size(); ++i) {185 if (&m_buttons[i].get() == element) {186 m_buttonValues[i] = element->normalizedValue();187 break;188 }189 }190 } else if (element->isAxis()) {191 for (unsigned i = 0; i < m_axes.size(); ++i) {192 if (&m_axes[i].get() == element) {193 m_axisValues[i] = element->normalizedValue();194 break;195 }196 }197 } else198 ASSERT_NOT_REACHED();199 200 77 m_lastUpdateTime = MonotonicTime::now(); 201 78 202 return element-> isButton() ? HIDInputType::ButtonPress : HIDInputType::NotAButtonPress;79 return element->gamepadValueChanged(value); 203 80 } 204 81 -
trunk/Source/WebCore/platform/gamepad/mac/HIDGamepad.h
r264475 r265079 28 28 #if ENABLE(GAMEPAD) && PLATFORM(MAC) 29 29 30 #include "HIDDevice.h" 31 #include "HIDGamepadElement.h" 30 32 #include "PlatformGamepad.h" 31 33 #include <IOKit/hid/IOHIDDevice.h> 32 34 #include <wtf/HashMap.h> 33 #include <wtf/RetainPtr.h>34 #include <wtf/UniqueRef.h>35 35 36 36 namespace WebCore { 37 37 38 struct HIDGamepadElement {39 WTF_MAKE_STRUCT_FAST_ALLOCATED;40 HIDGamepadElement(double theMin, double theMax, IOHIDElementRef element)41 : min(theMin)42 , max(theMax)43 , rawValue(theMin)44 , iohidElement(element)45 {46 }47 48 virtual ~HIDGamepadElement()49 {50 }51 52 double min;53 double max;54 double rawValue;55 RetainPtr<IOHIDElementRef> iohidElement;56 57 virtual bool isButton() const { return false; }58 virtual bool isAxis() const { return false; }59 60 virtual double normalizedValue() = 0;61 };62 63 struct HIDGamepadButton : HIDGamepadElement {64 HIDGamepadButton(uint32_t thePriority, double min, double max, IOHIDElementRef element)65 : HIDGamepadElement(min, max, element)66 , priority(thePriority)67 {68 }69 70 uint32_t priority;71 72 bool isButton() const final { return true; }73 74 // Buttons normalize to the range (0.0) - (1.0)75 double normalizedValue() override76 {77 return (rawValue - min) / (max - min);78 }79 };80 81 struct HIDGamepadAxis : HIDGamepadElement {82 HIDGamepadAxis(double min, double max, IOHIDElementRef element)83 : HIDGamepadElement(min, max, element)84 {85 }86 87 bool isAxis() const final { return true; }88 89 // Axes normalize to the range (-1.0) - (1.0)90 double normalizedValue() override91 {92 return (((rawValue - min) / (max - min)) * 2) - 1;93 }94 };95 96 enum class HIDInputType {97 ButtonPress,98 NotAButtonPress,99 };100 101 38 class HIDGamepad : public PlatformGamepad { 102 39 public: 103 HIDGamepad(IOHIDDeviceRef, unsigned index);40 static std::unique_ptr<HIDGamepad> create(IOHIDDeviceRef, unsigned index); 104 41 105 IOHIDDeviceRef hidDevice() const { return m_hidDevice.get(); }42 const HIDDevice& hidDevice() const { return m_device; } 106 43 44 void initialize(); 107 45 HIDInputType valueChanged(IOHIDValueRef); 108 46 109 const Vector< double>& axisValues() const final { return m_axisValues; }110 const Vector< double>& buttonValues() const final { return m_buttonValues; }47 const Vector<SharedGamepadValue>& axisValues() const final { return m_axisValues; } 48 const Vector<SharedGamepadValue>& buttonValues() const final { return m_buttonValues; } 111 49 112 50 const char* source() const final { return "HID"_s; } 113 51 52 protected: 53 HIDGamepad(HIDDevice&&, unsigned index); 54 55 virtual String id() = 0; 56 57 HashMap<IOHIDElementCookie, std::unique_ptr<HIDGamepadElement>> m_elementMap; 58 Vector<SharedGamepadValue> m_buttonValues; 59 Vector<SharedGamepadValue> m_axisValues; 60 114 61 private: 115 void initElements(); 116 void initElementsFromArray(CFArrayRef); 117 118 bool maybeAddButton(IOHIDElementRef); 119 bool maybeAddAxis(IOHIDElementRef); 120 121 void getCurrentValueForElement(const HIDGamepadElement&); 122 123 RetainPtr<IOHIDDeviceRef> m_hidDevice; 124 125 HashMap<IOHIDElementCookie, HIDGamepadElement*> m_elementMap; 126 127 Vector<UniqueRef<HIDGamepadButton>> m_buttons; 128 Vector<UniqueRef<HIDGamepadAxis>> m_axes; 129 Vector<double> m_buttonValues; 130 Vector<double> m_axisValues; 62 HIDDevice m_device; 131 63 }; 132 64 -
trunk/Source/WebCore/platform/gamepad/mac/HIDGamepadElement.h
r265078 r265079 1 1 /* 2 * Copyright (C) 20 14Apple Inc. All rights reserved.2 * Copyright (C) 2020 Apple Inc. All rights reserved. 3 3 * 4 4 * Redistribution and use in source and binary forms, with or without … … 26 26 #pragma once 27 27 28 #if ENABLE(GAMEPAD) 28 #if ENABLE(GAMEPAD) && PLATFORM(MAC) 29 29 30 #include <wtf/Forward.h> 31 #include <wtf/MonotonicTime.h> 32 #include <wtf/text/WTFString.h> 30 #include "HIDElement.h" 31 #include "SharedGamepadValue.h" 32 #include <wtf/HashMap.h> 33 #include <wtf/RetainPtr.h> 34 #include <wtf/UniqueRef.h> 33 35 34 36 namespace WebCore { 35 37 36 class PlatformGamepad { 38 enum class HIDInputType { 39 ButtonPress, 40 NotAButtonPress, 41 }; 42 43 class HIDGamepadElement : public HIDElement { 37 44 WTF_MAKE_FAST_ALLOCATED; 38 45 public: 39 virtual ~ PlatformGamepad() = default;46 virtual ~HIDGamepadElement() { } 40 47 41 const String& id() const { return m_id; } 42 const String& mapping() const { return m_mapping; } 43 unsigned index() const { return m_index; } 44 virtual MonotonicTime lastUpdateTime() const { return m_lastUpdateTime; } 45 MonotonicTime connectTime() const { return m_connectTime; } 46 virtual const Vector<double>& axisValues() const = 0; 47 virtual const Vector<double>& buttonValues() const = 0; 48 virtual double normalizedValue(); 49 virtual HIDInputType gamepadValueChanged(IOHIDValueRef) = 0; 48 50 49 v irtual const char* source() const { return "Unknown"_s; }51 void refreshCurrentValue(); 50 52 51 53 protected: 52 explicit PlatformGamepad(unsigned index) 53 : m_index(index) 54 HIDGamepadElement(const HIDElement&, SharedGamepadValue&); 55 56 virtual bool isButton() const { return false; } 57 virtual bool isAxis() const { return false; } 58 59 SharedGamepadValue m_value; 60 }; 61 62 class HIDGamepadButton final : public HIDGamepadElement { 63 public: 64 HIDGamepadButton(const HIDElement& element, SharedGamepadValue& value) 65 : HIDGamepadElement(element, value) 54 66 { 55 67 } 56 68 57 String m_id; 58 String m_mapping; 59 unsigned m_index; 60 MonotonicTime m_lastUpdateTime; 61 MonotonicTime m_connectTime; 69 bool isButton() const final { return true; } 70 71 private: 72 HIDInputType gamepadValueChanged(IOHIDValueRef) override; 73 }; 74 75 class HIDGamepadAxis final : public HIDGamepadElement { 76 public: 77 HIDGamepadAxis(const HIDElement& element, SharedGamepadValue& value) 78 : HIDGamepadElement(element, value) 79 { 80 } 81 82 bool isAxis() const final { return true; } 83 double normalizedValue() final; 84 85 private: 86 HIDInputType gamepadValueChanged(IOHIDValueRef) override; 62 87 }; 63 88 64 89 } // namespace WebCore 65 90 66 #endif // ENABLE(GAMEPAD) 91 #endif // ENABLE(GAMEPAD) && PLATFORM(MAC) -
trunk/Source/WebCore/platform/gamepad/mac/HIDGamepadProvider.mm
r264874 r265079 236 236 237 237 unsigned index = indexForNewlyConnectedDevice(); 238 std::unique_ptr<HIDGamepad> gamepad = makeUnique<HIDGamepad>(device, index);238 auto gamepad = HIDGamepad::create(device, index); 239 239 240 240 if (m_gamepadVector.size() <= index) -
trunk/Source/WebCore/platform/gamepad/mac/MultiGamepadProvider.h
r264769 r265079 64 64 Vector<PlatformGamepad*> m_gamepadVector; 65 65 66 // We create our own Gamepad type - to wrap both HID and GameControl er gamepads -66 // We create our own Gamepad type - to wrap both HID and GameController gamepads - 67 67 // because MultiGamepadProvider needs to manage the indexes of its own gamepads 68 68 // no matter what the HID or GameController index is. … … 79 79 80 80 MonotonicTime lastUpdateTime() const final { return m_platformGamepad->lastUpdateTime(); } 81 const Vector< double>& axisValues() const final { return m_platformGamepad->axisValues(); }82 const Vector< double>& buttonValues() const final { return m_platformGamepad->buttonValues(); }81 const Vector<SharedGamepadValue>& axisValues() const final { return m_platformGamepad->axisValues(); } 82 const Vector<SharedGamepadValue>& buttonValues() const final { return m_platformGamepad->buttonValues(); } 83 83 84 84 const char* source() const final { return m_platformGamepad->source(); } -
trunk/Source/WebCore/platform/graphics/cocoa/SourceBufferParserWebM.cpp
r265073 r265079 39 39 #include "VP9UtilitiesCocoa.h" 40 40 #include "VideoTrackPrivateWebM.h" 41 #include "VideoToolboxSoftLink.h" 41 42 #include <JavaScriptCore/DataView.h> 42 43 #include <pal/cf/CoreMediaSoftLink.h> -
trunk/Source/WebCore/platform/mac/HIDDevice.h
r265078 r265079 1 1 /* 2 * Copyright (C) 20 14Apple Inc. All rights reserved.2 * Copyright (C) 2020 Apple Inc. All rights reserved. 3 3 * 4 4 * Redistribution and use in source and binary forms, with or without … … 26 26 #pragma once 27 27 28 #if ENABLE(GAMEPAD)28 #if PLATFORM(MAC) 29 29 30 30 #include <wtf/Forward.h> 31 #include <wtf/MonotonicTime.h> 32 #include <wtf/text/WTFString.h> 31 #include <wtf/RetainPtr.h> 32 33 typedef struct CF_BRIDGED_TYPE(id) __IOHIDDevice * IOHIDDeviceRef; 33 34 34 35 namespace WebCore { 35 36 36 class PlatformGamepad { 37 class HIDElement; 38 39 class HIDDevice { 37 40 WTF_MAKE_FAST_ALLOCATED; 38 41 public: 39 virtual ~PlatformGamepad() = default;42 explicit HIDDevice(IOHIDDeviceRef); 40 43 41 const String& id() const { return m_id; } 42 const String& mapping() const { return m_mapping; } 43 unsigned index() const { return m_index; } 44 virtual MonotonicTime lastUpdateTime() const { return m_lastUpdateTime; } 45 MonotonicTime connectTime() const { return m_connectTime; } 46 virtual const Vector<double>& axisValues() const = 0; 47 virtual const Vector<double>& buttonValues() const = 0; 44 IOHIDDeviceRef rawElement() const { return m_rawDevice.get(); } 48 45 49 virtual const char* source() const { return "Unknown"_s; } 46 // Walks the collection tree of all elements in the device as presented by IOKit. 47 // Adds each unique input element to the vector in the tree traversal order it was encountered. 48 // "Unique" is defined as "having a different IOHIDElementCookie from any previously added element" 49 Vector<HIDElement> uniqueInputElementsInDeviceTreeOrder() const; 50 50 51 protected: 52 explicit PlatformGamepad(unsigned index) 53 : m_index(index) 54 { 55 } 51 uint16_t vendorID() const { return m_vendorID; } 52 uint16_t productID() const { return m_productID; } 53 const String& productName() const { return m_productName; } 56 54 57 String m_id; 58 String m_mapping; 59 unsigned m_index; 60 MonotonicTime m_lastUpdateTime; 61 MonotonicTime m_connectTime; 55 private: 56 RetainPtr<IOHIDDeviceRef> m_rawDevice; 57 58 uint16_t m_vendorID; 59 uint16_t m_productID; 60 String m_productName; 62 61 }; 63 62 64 63 } // namespace WebCore 65 64 66 #endif // ENABLE(GAMEPAD)65 #endif // PLATFORM(MAC) -
trunk/Source/WebCore/platform/mac/HIDElement.cpp
r265078 r265079 1 1 /* 2 * Copyright (C) 20 16Apple Inc. All rights reserved.2 * Copyright (C) 2020 Apple Inc. All rights reserved. 3 3 * 4 4 * Redistribution and use in source and binary forms, with or without … … 24 24 */ 25 25 26 #pragma once 26 #include "config.h" 27 #include "HIDElement.h" 27 28 28 #if ENABLE(GAMEPAD)29 #if PLATFORM(MAC) 29 30 30 #include <wtf/MonotonicTime.h> 31 #include <wtf/Vector.h> 32 #include <wtf/text/WTFString.h> 31 #include <IOKit/hid/IOHIDValue.h> 33 32 34 33 namespace WebCore { 35 class PlatformGamepad; 34 35 HIDElement::HIDElement(IOHIDElementRef element) 36 : m_physicalMin(IOHIDElementGetPhysicalMin(element)) 37 , m_physicalMax(IOHIDElementGetPhysicalMax(element)) 38 , m_physicalValue(m_physicalMin) 39 , m_usage(IOHIDElementGetUsage(element)) 40 , m_usagePage(IOHIDElementGetUsagePage(element)) 41 , m_cookie(IOHIDElementGetCookie(element)) 42 , m_rawElement(element) 43 { 36 44 } 37 45 38 namespace WebKit { 46 void HIDElement::valueChanged(IOHIDValueRef value) 47 { 48 if (IOHIDValueGetElement(value) != m_rawElement.get()) { 49 LOG(HID, "HIDElement: Changed value whose IOHIDElement %p doesn't match %p", IOHIDValueGetElement(value), m_rawElement.get()); 50 return; 51 } 39 52 40 class GamepadData; 41 42 class UIGamepad { 43 WTF_MAKE_FAST_ALLOCATED; 44 public: 45 UIGamepad(WebCore::PlatformGamepad&); 46 47 unsigned index() const { return m_index; } 48 49 GamepadData condensedGamepadData() const; 50 GamepadData fullGamepadData() const; 51 52 void updateFromPlatformGamepad(WebCore::PlatformGamepad&); 53 54 private: 55 unsigned m_index; 56 String m_id; 57 String m_mapping; 58 Vector<double> m_axisValues; 59 Vector<double> m_buttonValues; 60 MonotonicTime m_lastUpdateTime; 61 }; 62 53 m_physicalValue = IOHIDValueGetScaledValue(value, kIOHIDValueScaleTypePhysical); 63 54 } 64 55 65 #endif // ENABLE(GAMEPAD) 56 } // namespace WebCore 57 58 #endif // PLATFORM(MAC) -
trunk/Source/WebCore/platform/mac/HIDElement.h
r265078 r265079 1 1 /* 2 * Copyright (C) 20 16Apple Inc. All rights reserved.2 * Copyright (C) 2020 Apple Inc. All rights reserved. 3 3 * 4 4 * Redistribution and use in source and binary forms, with or without … … 26 26 #pragma once 27 27 28 #if ENABLE(GAMEPAD)28 #if PLATFORM(MAC) 29 29 30 #include <wtf/MonotonicTime.h> 31 #include <wtf/Vector.h> 32 #include <wtf/text/WTFString.h> 30 #include <IOKit/hid/IOHIDDevice.h> 31 #include <wtf/RetainPtr.h> 33 32 34 33 namespace WebCore { 35 class PlatformGamepad;36 }37 34 38 namespace WebKit { 39 40 class GamepadData; 41 42 class UIGamepad { 35 class HIDElement { 43 36 WTF_MAKE_FAST_ALLOCATED; 44 37 public: 45 UIGamepad(WebCore::PlatformGamepad&);38 explicit HIDElement(IOHIDElementRef); 46 39 47 unsigned index() const { return m_index; }40 IOHIDElementRef rawElement() const { return m_rawElement.get(); } 48 41 49 GamepadData condensedGamepadData() const; 50 GamepadData fullGamepadData() const; 42 CFIndex physicalMin() const { return m_physicalMin; } 43 CFIndex physicalMax() const { return m_physicalMax; } 44 CFIndex physicalValue() const { return m_physicalValue; } 45 uint32_t usage() const { return m_usage; } 46 uint32_t usagePage() const { return m_usagePage; } 47 IOHIDElementCookie cookie() const { return m_cookie; } 51 48 52 void updateFromPlatformGamepad(WebCore::PlatformGamepad&);49 void valueChanged(IOHIDValueRef); 53 50 54 51 private: 55 unsigned m_index; 56 String m_id; 57 String m_mapping; 58 Vector<double> m_axisValues; 59 Vector<double> m_buttonValues; 60 MonotonicTime m_lastUpdateTime; 52 CFIndex m_physicalMin; 53 CFIndex m_physicalMax; 54 CFIndex m_physicalValue; 55 uint32_t m_usage; 56 uint32_t m_usagePage; 57 IOHIDElementCookie m_cookie; 58 RetainPtr<IOHIDElementRef> m_rawElement; 61 59 }; 62 60 63 }64 61 65 #endif // ENABLE(GAMEPAD) 62 } // namespace WebCore 63 64 #endif // PLATFORM(MAC) -
trunk/Source/WebCore/testing/MockGamepad.cpp
r256215 r265079 42 42 m_id = gamepadID; 43 43 m_mapping = mapping; 44 m_axisValues = Vector<double>(axisCount, 0.0); 45 m_buttonValues = Vector<double>(buttonCount, 0.0); 44 m_axisValues.clear(); 45 for (size_t i = 0; i < axisCount; ++i) 46 m_axisValues.append({ }); 47 m_buttonValues.clear(); 48 for (size_t i = 0; i < buttonCount; ++i) 49 m_buttonValues.append({ }); 46 50 m_lastUpdateTime = MonotonicTime::now(); 47 51 } … … 54 58 } 55 59 56 m_axisValues[index] = value;60 m_axisValues[index].setValue(value); 57 61 m_lastUpdateTime = MonotonicTime::now(); 58 62 return true; … … 66 70 } 67 71 68 m_buttonValues[index] = value;72 m_buttonValues[index].setValue(value); 69 73 m_lastUpdateTime = MonotonicTime::now(); 70 74 return true; -
trunk/Source/WebCore/testing/MockGamepad.h
r256215 r265079 36 36 MockGamepad(unsigned index, const String& gamepadID, const String& mapping, unsigned axisCount, unsigned buttonCount); 37 37 38 const Vector< double>& axisValues() const final { return m_axisValues; }39 const Vector< double>& buttonValues() const final { return m_buttonValues; }38 const Vector<SharedGamepadValue>& axisValues() const final { return m_axisValues; } 39 const Vector<SharedGamepadValue>& buttonValues() const final { return m_buttonValues; } 40 40 41 41 void updateDetails(const String& gamepadID, const String& mapping, unsigned axisCount, unsigned buttonCount); … … 44 44 45 45 private: 46 Vector< double> m_axisValues;47 Vector< double> m_buttonValues;46 Vector<SharedGamepadValue> m_axisValues; 47 Vector<SharedGamepadValue> m_buttonValues; 48 48 }; 49 49 -
trunk/Source/WebKit/ChangeLog
r265078 r265079 1 2020-07-30 Brady Eidson <beidson@apple.com> 2 3 Refactor HID gamepad code to be much less fragile and much easier to hack on. 4 https://bugs.webkit.org/show_bug.cgi?id=214910 5 6 Reviewed by Darin Adler. 7 8 * Shared/Gamepad/GamepadData.cpp: 9 (WebKit::GamepadData::GamepadData): 10 * Shared/Gamepad/GamepadData.h: 11 12 * UIProcess/Gamepad/UIGamepad.h: 13 14 * WebProcess/Gamepad/WebGamepad.cpp: 15 (WebKit::WebGamepad::axisValues const): 16 (WebKit::WebGamepad::buttonValues const): 17 (WebKit::WebGamepad::updateValues): 18 * WebProcess/Gamepad/WebGamepad.h: 19 1 20 2020-07-30 Commit Queue <commit-queue@webkit.org> 2 21 -
trunk/Source/WebKit/Shared/Gamepad/GamepadData.cpp
r256215 r265079 32 32 #include <wtf/text/StringBuilder.h> 33 33 34 using WebCore::SharedGamepadValue; 35 34 36 namespace WebKit { 35 37 36 GamepadData::GamepadData(unsigned index, const Vector< double>& axisValues, const Vector<double>& buttonValues, MonotonicTime lastUpdateTime)38 GamepadData::GamepadData(unsigned index, const Vector<SharedGamepadValue>& axisValues, const Vector<SharedGamepadValue>& buttonValues, MonotonicTime lastUpdateTime) 37 39 : m_index(index) 38 , m_axisValues( axisValues)39 , m_buttonValues( buttonValues)40 , m_axisValues(WTF::map(axisValues, [](const auto& value) { return value.value(); })) 41 , m_buttonValues(WTF::map(buttonValues, [](const auto& value) { return value.value(); })) 40 42 , m_lastUpdateTime(lastUpdateTime) 41 43 { 42 44 } 43 45 44 GamepadData::GamepadData(unsigned index, const String& id, const String& mapping, const Vector< double>& axisValues, const Vector<double>& buttonValues, MonotonicTime lastUpdateTime)46 GamepadData::GamepadData(unsigned index, const String& id, const String& mapping, const Vector<SharedGamepadValue>& axisValues, const Vector<SharedGamepadValue>& buttonValues, MonotonicTime lastUpdateTime) 45 47 : m_index(index) 46 48 , m_id(id) 47 49 , m_mapping(mapping) 48 , m_axisValues( axisValues)49 , m_buttonValues( buttonValues)50 , m_axisValues(WTF::map(axisValues, [](const auto& value) { return value.value(); })) 51 , m_buttonValues(WTF::map(buttonValues, [](const auto& value) { return value.value(); })) 50 52 , m_lastUpdateTime(lastUpdateTime) 51 53 { -
trunk/Source/WebKit/Shared/Gamepad/GamepadData.h
r256215 r265079 28 28 #if ENABLE(GAMEPAD) 29 29 30 #include <WebCore/SharedGamepadValue.h> 30 31 #include <wtf/MonotonicTime.h> 31 32 #include <wtf/Vector.h> … … 46 47 } 47 48 48 GamepadData(unsigned index, const Vector< double>& axisValues, const Vector<double>& buttonValues, MonotonicTime lastUpdateTime);49 GamepadData(unsigned index, const String& id, const String& mapping, const Vector< double>& axisValues, const Vector<double>& buttonValues, MonotonicTime lastUpdateTime);49 GamepadData(unsigned index, const Vector<WebCore::SharedGamepadValue>& axisValues, const Vector<WebCore::SharedGamepadValue>& buttonValues, MonotonicTime lastUpdateTime); 50 GamepadData(unsigned index, const String& id, const String& mapping, const Vector<WebCore::SharedGamepadValue>& axisValues, const Vector<WebCore::SharedGamepadValue>& buttonValues, MonotonicTime lastUpdateTime); 50 51 51 52 void encode(IPC::Encoder&) const; -
trunk/Source/WebKit/UIProcess/Gamepad/UIGamepad.h
r256215 r265079 28 28 #if ENABLE(GAMEPAD) 29 29 30 #include <WebCore/SharedGamepadValue.h> 30 31 #include <wtf/MonotonicTime.h> 31 32 #include <wtf/Vector.h> … … 56 57 String m_id; 57 58 String m_mapping; 58 Vector< double> m_axisValues;59 Vector< double> m_buttonValues;59 Vector<WebCore::SharedGamepadValue> m_axisValues; 60 Vector<WebCore::SharedGamepadValue> m_buttonValues; 60 61 MonotonicTime m_lastUpdateTime; 61 62 }; -
trunk/Source/WebKit/WebProcess/Gamepad/WebGamepad.cpp
r256215 r265079 32 32 #include "Logging.h" 33 33 34 using WebCore::SharedGamepadValue; 34 35 35 36 namespace WebKit { … … 48 49 } 49 50 50 const Vector< double>& WebGamepad::axisValues() const51 const Vector<SharedGamepadValue>& WebGamepad::axisValues() const 51 52 { 52 53 return m_axisValues; 53 54 } 54 55 55 const Vector< double>& WebGamepad::buttonValues() const56 const Vector<SharedGamepadValue>& WebGamepad::buttonValues() const 56 57 { 57 58 return m_buttonValues; … … 65 66 ASSERT(m_buttonValues.size() == gamepadData.buttonValues().size()); 66 67 67 m_axisValues = gamepadData.axisValues();68 m_buttonValues = gamepadData.buttonValues();69 68 69 m_axisValues = WTF::map(gamepadData.axisValues(), [](auto value) { return SharedGamepadValue(value); }); 70 m_buttonValues = WTF::map(gamepadData.buttonValues(), [](auto value) { return SharedGamepadValue(value); }); 70 71 m_lastUpdateTime = gamepadData.lastUpdateTime(); 71 72 } -
trunk/Source/WebKit/WebProcess/Gamepad/WebGamepad.h
r204853 r265079 40 40 WebGamepad(const GamepadData&); 41 41 42 const Vector< double>& axisValues() const override;43 const Vector< double>& buttonValues() const override;42 const Vector<WebCore::SharedGamepadValue>& axisValues() const override; 43 const Vector<WebCore::SharedGamepadValue>& buttonValues() const override; 44 44 45 45 void updateValues(const GamepadData&); 46 46 47 47 private: 48 Vector< double> m_axisValues;49 Vector< double> m_buttonValues;48 Vector<WebCore::SharedGamepadValue> m_axisValues; 49 Vector<WebCore::SharedGamepadValue> m_buttonValues; 50 50 }; 51 51 -
trunk/Tools/ChangeLog
r265077 r265079 1 2020-07-30 Brady Eidson <beidson@apple.com> 2 3 Refactor HID gamepad code to be much less fragile and much easier to hack on. 4 https://bugs.webkit.org/show_bug.cgi?id=214910 5 6 Reviewed by Darin Adler. 7 8 Add a test that verifies connect, basic button/axis changes, and disconnect of a HID gamepad. 9 10 * TestWebKitAPI/Tests/mac/HIDGamepads.mm: 11 1 12 2020-07-29 Fujii Hironori <Hironori.Fujii@sony.com> 2 13 -
trunk/Tools/TestWebKitAPI/Tests/mac/HIDGamepads.mm
r264874 r265079 30 30 #import "InstanceMethodSwizzler.h" 31 31 #import "PlatformUtilities.h" 32 #import "Test.h" 32 33 #import "TestURLSchemeHandler.h" 33 34 #import "TestWKWebView.h" … … 60 61 } 61 62 63 function handleGamepadDisconnect(evt) 64 { 65 window.webkit.messageHandlers.gamepad.postMessage("Disconnect: " + JSON.stringify(evt.gamepad.id)); 66 } 67 62 68 addEventListener("gamepadconnected", handleGamepadConnect); 69 addEventListener("gamepaddisconnected", handleGamepadDisconnect); 63 70 64 71 </script> … … 197 204 } 198 205 206 static const char* pollGamepadStateFunction = R"GAMEPADRESOURCE( 207 var result = new Object(); 208 var gamepads = navigator.getGamepads(); 209 result.gamepadCount = gamepads.length; 210 result.gamepadButtons = new Array; 211 result.gamepadAxes = new Array; 212 213 for (var i = 0; i < gamepads.length; ++i) { 214 result.gamepadButtons[i] = new Array; 215 for (var j = 0; j < gamepads[i].buttons.length; ++j) 216 result.gamepadButtons[i][j] = gamepads[i].buttons[j].value; 217 218 result.gamepadAxes[i] = new Array; 219 for (var j = 0; j < gamepads[i].axes.length; ++j) 220 result.gamepadAxes[i][j] = gamepads[i].axes[j]; 221 } 222 223 return result; 224 225 )GAMEPADRESOURCE"; 226 227 TEST(Gamepad, GamepadState) 228 { 229 auto keyWindowSwizzler = makeUnique<InstanceMethodSwizzler>([NSApplication class], @selector(keyWindow), reinterpret_cast<IMP>(getKeyWindowForTesting)); 230 231 auto configuration = adoptNS([[WKWebViewConfiguration alloc] init]); 232 auto messageHandler = adoptNS([[GamepadMessageHandler alloc] init]); 233 [[configuration userContentController] addScriptMessageHandler:messageHandler.get() name:@"gamepad"]; 234 235 auto schemeHandler = adoptNS([[TestURLSchemeHandler alloc] init]); 236 [configuration setURLSchemeHandler:schemeHandler.get() forURLScheme:@"gamepad"]; 237 238 [schemeHandler setStartURLSchemeTaskHandler:^(WKWebView *, id<WKURLSchemeTask> task) { 239 auto response = adoptNS([[NSURLResponse alloc] initWithURL:task.request.URL MIMEType:@"text/html" expectedContentLength:0 textEncodingName:nil]); 240 [task didReceiveResponse:response.get()]; 241 [task didReceiveData:[NSData dataWithBytes:mainBytes length:strlen(mainBytes)]]; 242 [task didFinish]; 243 }]; 244 245 auto webView = adoptNS([[TestWKWebView alloc] initWithFrame:NSMakeRect(0, 0, 800, 600) configuration:configuration.get()]); 246 keyWindowForTesting = [webView window]; 247 [webView synchronouslyLoadRequest:[NSURLRequest requestWithURL:[NSURL URLWithString:@"gamepad://host/main.html"]]]; 248 249 [[webView window] makeFirstResponder:webView.get()]; 250 251 // Resigning/reinstating the key window state triggers the "key window did change" notification that WKWebView currently 252 // needs to convince it to monitor gamepad devices 253 [[webView window] resignKeyWindow]; 254 [[webView window] makeKeyWindow]; 255 256 // Connect a gamepad and make it visible to the page 257 auto gamepad = makeUnique<VirtualGamepad>(VirtualGamepad::shenzhenLongshengweiTechnologyGamepadMapping()); 258 while (![webView.get().configuration.processPool _numberOfConnectedGamepadsForTesting]) 259 Util::sleep(0.01); 260 261 Vector<double> expectedButtons = { 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 }; 262 Vector<double> expectedAxes = { -0.9921568627450981, -0.003921568627450966, -0.003921568627450966, -0.003921568627450966, -0.003921568627450966 }; 263 264 auto updateStateAndPublish = [&] { 265 for (size_t i = 0; i < expectedButtons.size(); ++i) 266 gamepad->setButtonValue(i, expectedButtons[i]); 267 for (size_t i = 0; i < 5; ++i) 268 gamepad->setAxisValue(i, expectedAxes[i]); 269 gamepad->publishReport(); 270 }; 271 272 updateStateAndPublish(); 273 274 // Wait for the page to tell us a gamepad connected 275 Util::run(&didReceiveMessage); 276 didReceiveMessage = false; 277 278 EXPECT_EQ(messageHandler.get().messages.size(), 1u); 279 EXPECT_TRUE([messageHandler.get().messages[0] isEqualToString:@"\"79-11-Virtual Shenzhen Longshengwei Technology Gamepad\""]); 280 281 bool done = false; 282 bool gotNewValues = false; 283 auto resultBlock = [&] (id result, NSError *error) { 284 EXPECT_NULL(error); 285 EXPECT_TRUE([result[@"gamepadCount"] isEqualToNumber:@(1)]); 286 287 bool areEqual = true; 288 289 for (size_t i = 0; i < 10; ++i) { 290 if (!WTF::areEssentiallyEqual([(NSNumber *)result[@"gamepadButtons"][0][i] doubleValue], expectedButtons[i])) 291 areEqual = false; 292 } 293 294 for (size_t i = 0; i < 5; ++i) { 295 if (!WTF::areEssentiallyEqual([(NSNumber *)result[@"gamepadAxes"][0][i] doubleValue], expectedAxes[i])) 296 areEqual = false; 297 } 298 299 if (areEqual) 300 gotNewValues = true; 301 302 done = true; 303 }; 304 305 // Change some buttons, polling state to confirm 306 NSDate *start = [NSDate date]; 307 while (!gotNewValues) { 308 [webView callAsyncJavaScript:@(pollGamepadStateFunction) arguments:nil inFrame:nil inContentWorld:WKContentWorld.pageWorld completionHandler:resultBlock]; 309 Util::run(&done); 310 done = false; 311 312 if ([[NSDate date] timeIntervalSinceDate:start] > 1.0) 313 break; 314 } 315 EXPECT_TRUE(gotNewValues); 316 gotNewValues = false; 317 318 expectedButtons = { 0.0, 1.0, 1.0, 1.0, 1.0, 1.0, 0.0, 0.0, 1.0, 1.0 }; 319 updateStateAndPublish(); 320 321 start = [NSDate date]; 322 while (!gotNewValues) { 323 [webView callAsyncJavaScript:@(pollGamepadStateFunction) arguments:nil inFrame:nil inContentWorld:WKContentWorld.pageWorld completionHandler:resultBlock]; 324 Util::run(&done); 325 done = false; 326 327 if ([[NSDate date] timeIntervalSinceDate:start] > 1.0) 328 break; 329 } 330 EXPECT_TRUE(gotNewValues); 331 gotNewValues = false; 332 333 expectedAxes = { -1.0, -1.0, -1.0, -1.0, 1.0 }; 334 updateStateAndPublish(); 335 336 // Even though we set -1.0 for each "X" axis, the first 3 axes on this controller are always constant 337 expectedAxes = { -0.9921568627450981, -0.003921568627450966, -0.003921568627450966, -1.0, 1.0 }; 338 339 start = [NSDate date]; 340 while (!gotNewValues) { 341 [webView callAsyncJavaScript:@(pollGamepadStateFunction) arguments:nil inFrame:nil inContentWorld:WKContentWorld.pageWorld completionHandler:resultBlock]; 342 Util::run(&done); 343 done = false; 344 345 if ([[NSDate date] timeIntervalSinceDate:start] > 1.0) 346 break; 347 } 348 EXPECT_TRUE(gotNewValues); 349 gotNewValues = false; 350 351 // Disconnect the gamepad 352 gamepad = nullptr; 353 354 Util::run(&didReceiveMessage); 355 didReceiveMessage = false; 356 357 EXPECT_EQ(messageHandler.get().messages.size(), 2u); 358 EXPECT_TRUE([messageHandler.get().messages[1] isEqualToString:@"Disconnect: \"79-11-Virtual Shenzhen Longshengwei Technology Gamepad\""]); 359 } 360 199 361 } // namespace TestWebKitAPI 200 362
Note: See TracChangeset
for help on using the changeset viewer.