summaryrefslogtreecommitdiffstats
path: root/dom/gamepad/ipc/GamepadTestChannelParent.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'dom/gamepad/ipc/GamepadTestChannelParent.cpp')
-rw-r--r--dom/gamepad/ipc/GamepadTestChannelParent.cpp129
1 files changed, 129 insertions, 0 deletions
diff --git a/dom/gamepad/ipc/GamepadTestChannelParent.cpp b/dom/gamepad/ipc/GamepadTestChannelParent.cpp
new file mode 100644
index 0000000000..1c8d67491e
--- /dev/null
+++ b/dom/gamepad/ipc/GamepadTestChannelParent.cpp
@@ -0,0 +1,129 @@
+/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* vim: set ts=8 sts=2 et sw=2 tw=80: */
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#include "GamepadTestChannelParent.h"
+
+#include "mozilla/dom/GamepadPlatformService.h"
+#include "mozilla/ipc/BackgroundParent.h"
+#include "mozilla/StaticPrefs_dom.h"
+#include "mozilla/Unused.h"
+
+namespace mozilla::dom {
+
+already_AddRefed<GamepadTestChannelParent> GamepadTestChannelParent::Create() {
+ // Refuse to create the parent actor if this pref is disabled
+ if (!StaticPrefs::dom_gamepad_test_enabled()) {
+ return nullptr;
+ }
+
+ return RefPtr<GamepadTestChannelParent>(new GamepadTestChannelParent())
+ .forget();
+}
+
+GamepadTestChannelParent::GamepadTestChannelParent() {
+ ::mozilla::ipc::AssertIsOnBackgroundThread();
+ GamepadMonitoringState::GetSingleton().AddObserver(this);
+}
+
+GamepadTestChannelParent::~GamepadTestChannelParent() {
+ ::mozilla::ipc::AssertIsOnBackgroundThread();
+ GamepadMonitoringState::GetSingleton().RemoveObserver(this);
+}
+
+void GamepadTestChannelParent::AddGamepadToPlatformService(
+ uint32_t aPromiseId, const GamepadAdded& aGamepadAdded) {
+ mozilla::ipc::AssertIsOnBackgroundThread();
+
+ RefPtr<GamepadPlatformService> service =
+ GamepadPlatformService::GetParentService();
+ MOZ_ASSERT(service);
+
+ const GamepadAdded& a = aGamepadAdded;
+ nsCString gamepadID;
+ LossyCopyUTF16toASCII(a.id(), gamepadID);
+ GamepadHandle handle = service->AddGamepad(
+ gamepadID.get(), static_cast<GamepadMappingType>(a.mapping()), a.hand(),
+ a.num_buttons(), a.num_axes(), a.num_haptics(), a.num_lights(),
+ a.num_touches());
+
+ Unused << SendReplyGamepadHandle(aPromiseId, handle);
+}
+
+void GamepadTestChannelParent::OnMonitoringStateChanged(bool aNewState) {
+ mozilla::ipc::AssertIsOnBackgroundThread();
+
+ if (aNewState) {
+ for (auto& deferredGamepadAdd : mDeferredGamepadAdded) {
+ AddGamepadToPlatformService(deferredGamepadAdd.promiseId,
+ deferredGamepadAdd.gamepadAdded);
+ }
+ mDeferredGamepadAdded.Clear();
+ }
+}
+
+mozilla::ipc::IPCResult GamepadTestChannelParent::RecvGamepadTestEvent(
+ const uint32_t& aID, const GamepadChangeEvent& aEvent) {
+ mozilla::ipc::AssertIsOnBackgroundThread();
+
+ RefPtr<GamepadPlatformService> service =
+ GamepadPlatformService::GetParentService();
+ MOZ_ASSERT(service);
+
+ const GamepadChangeEventBody& body = aEvent.body();
+
+ // GamepadAdded is special because it will be deferred if monitoring hasn't
+ // started. Everything else won't be deferred and will fail if monitoring
+ // isn't running
+ if (body.type() == GamepadChangeEventBody::TGamepadAdded) {
+ if (GamepadMonitoringState::GetSingleton().IsMonitoring()) {
+ AddGamepadToPlatformService(aID, body.get_GamepadAdded());
+ } else {
+ mDeferredGamepadAdded.AppendElement(
+ DeferredGamepadAdded{aID, body.get_GamepadAdded()});
+ }
+ return IPC_OK();
+ }
+
+ if (!GamepadMonitoringState::GetSingleton().IsMonitoring()) {
+ return IPC_FAIL(this, "Simulated message received while not monitoring");
+ }
+
+ GamepadHandle handle = aEvent.handle();
+
+ switch (body.type()) {
+ case GamepadChangeEventBody::TGamepadRemoved:
+ service->RemoveGamepad(handle);
+ break;
+ case GamepadChangeEventBody::TGamepadButtonInformation: {
+ const GamepadButtonInformation& a = body.get_GamepadButtonInformation();
+ service->NewButtonEvent(handle, a.button(), a.pressed(), a.touched(),
+ a.value());
+ break;
+ }
+ case GamepadChangeEventBody::TGamepadAxisInformation: {
+ const GamepadAxisInformation& a = body.get_GamepadAxisInformation();
+ service->NewAxisMoveEvent(handle, a.axis(), a.value());
+ break;
+ }
+ case GamepadChangeEventBody::TGamepadPoseInformation: {
+ const GamepadPoseInformation& a = body.get_GamepadPoseInformation();
+ service->NewPoseEvent(handle, a.pose_state());
+ break;
+ }
+ case GamepadChangeEventBody::TGamepadTouchInformation: {
+ const GamepadTouchInformation& a = body.get_GamepadTouchInformation();
+ service->NewMultiTouchEvent(handle, a.index(), a.touch_state());
+ break;
+ }
+ default:
+ NS_WARNING("Unknown event type.");
+ return IPC_FAIL_NO_REASON(this);
+ }
+ Unused << SendReplyGamepadHandle(aID, handle);
+ return IPC_OK();
+}
+
+} // namespace mozilla::dom