GamepadTestChannelParent.cpp (4525B)
1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ 2 /* vim: set ts=8 sts=2 et sw=2 tw=80: */ 3 /* This Source Code Form is subject to the terms of the Mozilla Public 4 * License, v. 2.0. If a copy of the MPL was not distributed with this 5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 6 7 #include "GamepadTestChannelParent.h" 8 9 #include "mozilla/StaticPrefs_dom.h" 10 #include "mozilla/dom/GamepadPlatformService.h" 11 #include "mozilla/ipc/BackgroundParent.h" 12 13 namespace mozilla::dom { 14 15 already_AddRefed<GamepadTestChannelParent> GamepadTestChannelParent::Create() { 16 // Refuse to create the parent actor if this pref is disabled 17 if (!StaticPrefs::dom_gamepad_test_enabled()) { 18 return nullptr; 19 } 20 21 return RefPtr<GamepadTestChannelParent>(new GamepadTestChannelParent()) 22 .forget(); 23 } 24 25 GamepadTestChannelParent::GamepadTestChannelParent() { 26 ::mozilla::ipc::AssertIsOnBackgroundThread(); 27 GamepadMonitoringState::GetSingleton().AddObserver(this); 28 } 29 30 GamepadTestChannelParent::~GamepadTestChannelParent() { 31 ::mozilla::ipc::AssertIsOnBackgroundThread(); 32 GamepadMonitoringState::GetSingleton().RemoveObserver(this); 33 } 34 35 void GamepadTestChannelParent::AddGamepadToPlatformService( 36 uint32_t aPromiseId, const GamepadAdded& aGamepadAdded) { 37 mozilla::ipc::AssertIsOnBackgroundThread(); 38 39 RefPtr<GamepadPlatformService> service = 40 GamepadPlatformService::GetParentService(); 41 MOZ_ASSERT(service); 42 43 const GamepadAdded& a = aGamepadAdded; 44 nsCString gamepadID; 45 LossyCopyUTF16toASCII(a.id(), gamepadID); 46 GamepadHandle handle = service->AddGamepad( 47 gamepadID.get(), static_cast<GamepadMappingType>(a.mapping()), a.hand(), 48 a.num_buttons(), a.num_axes(), a.num_haptics(), a.num_lights(), 49 a.num_touches()); 50 51 (void)SendReplyGamepadHandle(aPromiseId, handle); 52 } 53 54 void GamepadTestChannelParent::OnMonitoringStateChanged(bool aNewState) { 55 mozilla::ipc::AssertIsOnBackgroundThread(); 56 57 if (aNewState) { 58 for (auto& deferredGamepadAdd : mDeferredGamepadAdded) { 59 AddGamepadToPlatformService(deferredGamepadAdd.promiseId, 60 deferredGamepadAdd.gamepadAdded); 61 } 62 mDeferredGamepadAdded.Clear(); 63 } 64 } 65 66 mozilla::ipc::IPCResult GamepadTestChannelParent::RecvGamepadTestEvent( 67 const uint32_t& aID, const GamepadChangeEvent& aEvent) { 68 mozilla::ipc::AssertIsOnBackgroundThread(); 69 70 RefPtr<GamepadPlatformService> service = 71 GamepadPlatformService::GetParentService(); 72 MOZ_ASSERT(service); 73 74 const GamepadChangeEventBody& body = aEvent.body(); 75 76 // GamepadAdded is special because it will be deferred if monitoring hasn't 77 // started. Everything else won't be deferred and will fail if monitoring 78 // isn't running 79 if (body.type() == GamepadChangeEventBody::TGamepadAdded) { 80 if (GamepadMonitoringState::GetSingleton().IsMonitoring()) { 81 AddGamepadToPlatformService(aID, body.get_GamepadAdded()); 82 } else { 83 mDeferredGamepadAdded.AppendElement( 84 DeferredGamepadAdded{aID, body.get_GamepadAdded()}); 85 } 86 return IPC_OK(); 87 } 88 89 if (!GamepadMonitoringState::GetSingleton().IsMonitoring()) { 90 return IPC_FAIL(this, "Simulated message received while not monitoring"); 91 } 92 93 GamepadHandle handle = aEvent.handle(); 94 95 switch (body.type()) { 96 case GamepadChangeEventBody::TGamepadRemoved: 97 service->RemoveGamepad(handle); 98 break; 99 case GamepadChangeEventBody::TGamepadButtonInformation: { 100 const GamepadButtonInformation& a = body.get_GamepadButtonInformation(); 101 service->NewButtonEvent(handle, a.button(), a.pressed(), a.touched(), 102 a.value()); 103 break; 104 } 105 case GamepadChangeEventBody::TGamepadAxisInformation: { 106 const GamepadAxisInformation& a = body.get_GamepadAxisInformation(); 107 service->NewAxisMoveEvent(handle, a.axis(), a.value()); 108 break; 109 } 110 case GamepadChangeEventBody::TGamepadPoseInformation: { 111 const GamepadPoseInformation& a = body.get_GamepadPoseInformation(); 112 service->NewPoseEvent(handle, a.pose_state()); 113 break; 114 } 115 case GamepadChangeEventBody::TGamepadTouchInformation: { 116 const GamepadTouchInformation& a = body.get_GamepadTouchInformation(); 117 service->NewMultiTouchEvent(handle, a.index(), a.touch_state()); 118 break; 119 } 120 default: 121 NS_WARNING("Unknown event type."); 122 return IPC_FAIL_NO_REASON(this); 123 } 124 (void)SendReplyGamepadHandle(aID, handle); 125 return IPC_OK(); 126 } 127 128 } // namespace mozilla::dom