Bug 1299928 - Part 3: Construct IPC channel between Gamepad and VRManager; r?kip draft
authorDaosheng Mu <daoshengmu@gmail.com>
Tue, 04 Oct 2016 16:30:04 +0800
changeset 425940 86c6b60dc10ad11d7a9a5e126ccafa856770d51f
parent 425939 1188d0db2c19b6382437f580c1315815932be891
child 425941 6a21b94110bc0a6debc3bb13d88461611e2b74a4
push id32537
push userbmo:dmu@mozilla.com
push dateMon, 17 Oct 2016 10:06:25 +0000
reviewerskip
bugs1299928
milestone52.0a1
Bug 1299928 - Part 3: Construct IPC channel between Gamepad and VRManager; r?kip MozReview-Commit-ID: 9hpxlLlIdh7
dom/gamepad/GamepadManager.cpp
dom/gamepad/GamepadManager.h
gfx/vr/gfxVR.h
gfx/vr/ipc/PVRManager.ipdl
gfx/vr/ipc/VRManagerChild.cpp
gfx/vr/ipc/VRManagerChild.h
gfx/vr/ipc/VRMessageUtils.h
gfx/vr/moz.build
--- a/dom/gamepad/GamepadManager.cpp
+++ b/dom/gamepad/GamepadManager.cpp
@@ -23,16 +23,17 @@
 #include "nsGlobalWindow.h"
 #include "nsIDOMEvent.h"
 #include "nsIDOMDocument.h"
 #include "nsIDOMWindow.h"
 #include "nsIObserver.h"
 #include "nsIObserverService.h"
 #include "nsIServiceManager.h"
 #include "nsThreadUtils.h"
+#include "VRManagerChild.h"
 #include "mozilla/Services.h"
 #include "mozilla/Unused.h"
 
 #include <cstddef>
 
 using namespace mozilla::ipc;
 
 namespace mozilla {
@@ -104,16 +105,21 @@ GamepadManager::Observe(nsISupports* aSu
 void
 GamepadManager::StopMonitoring()
 {
   for (uint32_t i = 0; i < mChannelChildren.Length(); ++i) {
     mChannelChildren[i]->SendGamepadListenerRemoved();
   }
   mChannelChildren.Clear();
   mGamepads.Clear();
+
+#if defined(XP_WIN) || defined(XP_MACOSX) || defined(XP_LINUX)
+  mVRChannelChild = gfx::VRManagerChild::Get();
+  mVRChannelChild->SendControllerListenerRemoved();
+#endif
 }
 
 void
 GamepadManager::BeginShutdown()
 {
   mShuttingDown = true;
   StopMonitoring();
   // Don't let windows call back to unregister during shutdown
@@ -610,18 +616,22 @@ GamepadManager::ActorCreated(PBackground
   if (NS_WARN_IF(!initedChild)) {
     ActorFailed();
     return;
   }
   MOZ_ASSERT(initedChild == child);
   child->SendGamepadListenerAdded();
   mChannelChildren.AppendElement(child);
 
-  // TODO: Add more event channels to mChannelChildren if you would
-  // like to support more kinds of devices.
+#if defined(XP_WIN) || defined(XP_MACOSX) || defined(XP_LINUX)
+  // Construct VRManagerChannel and ask adding the connected
+  // VR controllers to GamepadManager
+  mVRChannelChild = gfx::VRManagerChild::Get();
+  mVRChannelChild->SendControllerListenerAdded();
+#endif
 }
 
 //Override nsIIPCBackgroundChildCreateCallback
 void
 GamepadManager::ActorFailed()
 {
   MOZ_CRASH("Gamepad IPC actor create failed!");
 }
--- a/dom/gamepad/GamepadManager.h
+++ b/dom/gamepad/GamepadManager.h
@@ -10,16 +10,19 @@
 #include "nsIIPCBackgroundChildCreateCallback.h"
 #include "nsIObserver.h"
 // Needed for GamepadMappingType
 #include "mozilla/dom/GamepadBinding.h"
 
 class nsGlobalWindow;
 
 namespace mozilla {
+namespace gfx {
+class VRManagerChild;
+} // namespace gfx
 namespace dom {
 
 class EventTarget;
 class Gamepad;
 class GamepadChangeEvent;
 class GamepadEventChannelChild;
 
 class GamepadManager final : public nsIObserver,
@@ -108,16 +111,17 @@ class GamepadManager final : public nsIO
   // true when shutdown has begun
   bool mShuttingDown;
 
   // Gamepad IPDL child
   // This pointer is only used by this singleton instance and
   // will be destroyed during the IPDL shutdown chain, so we
   // don't need to refcount it here.
   nsTArray<GamepadEventChannelChild *> mChannelChildren;
+  gfx::VRManagerChild* mVRChannelChild;
 
  private:
 
   nsresult Init();
 
   bool MaybeWindowHasSeenGamepad(nsGlobalWindow* aWindow, uint32_t aIndex);
   // Returns true if we have already sent data from this gamepad
   // to this window. This should only return true if the user
--- a/gfx/vr/gfxVR.h
+++ b/gfx/vr/gfxVR.h
@@ -10,16 +10,17 @@
 #include "nsString.h"
 #include "nsCOMPtr.h"
 #include "mozilla/RefPtr.h"
 #include "mozilla/gfx/2D.h"
 #include "mozilla/Atomics.h"
 #include "mozilla/EnumeratedArray.h"
 #include "mozilla/TimeStamp.h"
 #include "mozilla/TypedEnumBits.h"
+#include "mozilla/dom/GamepadBinding.h"
 
 namespace mozilla {
 namespace layers {
 class PTextureParent;
 }
 namespace gfx {
 class VRLayerParent;
 class VRDisplayHost;
@@ -204,12 +205,42 @@ public:
   virtual void Destroy() = 0;
   virtual void GetHMDs(nsTArray<RefPtr<VRDisplayHost>>& aHMDResult) = 0;
 
 protected:
   VRDisplayManager() { }
   virtual ~VRDisplayManager() { }
 };
 
+struct VRControllerInfo
+{
+  VRDeviceType GetType() const { return mType; }
+  uint32_t GetControllerID() const { return mControllerID; }
+  const nsCString& GetControllerName() const { return mControllerName; }
+  dom::GamepadMappingType GetMappingType() const { return mMappingType; }
+  uint32_t GetNumButtons() const { return mNumButtons; }
+  uint32_t GetNumAxes() const { return mNumAxes; }
+
+  uint32_t mControllerID;
+  VRDeviceType mType;
+  nsCString mControllerName;
+  dom::GamepadMappingType mMappingType;
+  uint32_t mNumButtons;
+  uint32_t mNumAxes;
+
+  bool operator==(const VRControllerInfo& other) const {
+  return mType == other.mType &&
+         mControllerID == other.mControllerID &&
+         mControllerName == other.mControllerName &&
+         mMappingType == other.mMappingType &&
+         mNumButtons == other.mNumButtons &&
+         mNumAxes == other.mNumAxes;
+  }
+
+  bool operator!=(const VRControllerInfo& other) const {
+    return !(*this == other);
+  }
+};
+
 } // namespace gfx
 } // namespace mozilla
 
 #endif /* GFX_VR_H */
--- a/gfx/vr/ipc/PVRManager.ipdl
+++ b/gfx/vr/ipc/PVRManager.ipdl
@@ -5,23 +5,25 @@
  * 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 LayersSurfaces;
 include protocol PLayer;
 include protocol PTexture;
 include protocol PVRLayer;
 include LayersMessages;
+include GamepadEventTypes;
 
 include "VRMessageUtils.h";
 
 using struct mozilla::gfx::VRFieldOfView from "gfxVR.h";
 using struct mozilla::gfx::VRDisplayInfo from "gfxVR.h";
 using struct mozilla::gfx::VRSensorUpdate from "gfxVR.h";
 using struct mozilla::gfx::VRHMDSensorState from "gfxVR.h";
+using struct mozilla::gfx::VRControllerInfo from "gfxVR.h";
 using mozilla::layers::LayersBackend from "mozilla/layers/LayersTypes.h";
 using mozilla::layers::TextureFlags from "mozilla/layers/CompositorTypes.h";
 
 
 namespace mozilla {
 namespace gfx {
 
 /**
@@ -51,27 +53,34 @@ parent:
   // Reset the sensor of the display identified by aDisplayID so that the current
   // sensor state is the "Zero" position.
   async ResetSensor(uint32_t aDisplayID);
 
   sync GetSensorState(uint32_t aDisplayID) returns(VRHMDSensorState aState);
   sync GetImmediateSensorState(uint32_t aDisplayID) returns(VRHMDSensorState aState);
   sync SetHaveEventListener(bool aHaveEventListener);
 
+  async ControllerListenerAdded();
+  async ControllerListenerRemoved();
+  // GetControllers synchronously returns the VR controllers that have already been
+  // enumerated by RefreshVRControllers() but does not enumerate new ones.
+  sync GetControllers() returns(VRControllerInfo[] aControllerInfo);
+
 child:
 
   async ParentAsyncMessages(AsyncParentMessageData[] aMessages);
 
   // Notify children of updated VR display enumeration and details.  This will
   // be sent to all children when the parent receives RefreshDisplays, even
   // if no changes have been detected.  This ensures that Promises exposed
   // through DOM calls are always resolved.
   async UpdateDisplayInfo(VRDisplayInfo[] aDisplayUpdates);
 
   async NotifyVSync();
   async NotifyVRVSync(uint32_t aDisplayID);
+  async GamepadUpdate(GamepadChangeEvent aGamepadEvent);
 
   async __delete__();
 
 };
 
 } // gfx
 } // mozilla
--- a/gfx/vr/ipc/VRManagerChild.cpp
+++ b/gfx/vr/ipc/VRManagerChild.cpp
@@ -3,22 +3,24 @@
  */
 /* 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 "VRManagerChild.h"
 #include "VRManagerParent.h"
 #include "VRDisplayClient.h"
+#include "nsGlobalWindow.h"
 #include "mozilla/StaticPtr.h"
 #include "mozilla/layers/CompositorThread.h" // for CompositorThread
 #include "mozilla/dom/Navigator.h"
 #include "mozilla/dom/VREventObserver.h"
 #include "mozilla/dom/WindowBinding.h" // for FrameRequestCallback
 #include "mozilla/dom/ContentChild.h"
+#include "mozilla/dom/GamepadManager.h"
 #include "mozilla/layers/TextureClient.h"
 #include "nsContentUtils.h"
 
 using layers::TextureClient;
 
 namespace {
 const nsTArray<RefPtr<dom::VREventObserver>>::index_type kNoIndex =
   nsTArray<RefPtr<dom::VREventObserver> >::NoIndex;
@@ -476,16 +478,32 @@ VRManagerChild::RecvNotifyVRVSync(const 
     if (display->GetDisplayInfo().GetDisplayID() == aDisplayID) {
       display->NotifyVRVsync();
     }
   }
 
   return true;
 }
 
+bool
+VRManagerChild::RecvGamepadUpdate(const GamepadChangeEvent& aGamepadEvent)
+{
+  // VRManagerChild could be at other processes,
+  // but GamepadManager is only allowed to be run at Content process.
+  if (XRE_IsContentProcess()) {
+    RefPtr<dom::GamepadManager> serivce(dom::GamepadManager::GetService());
+
+    if (serivce) {
+      serivce->Update(aGamepadEvent);
+    }
+  }
+
+  return true;
+}
+
 void
 VRManagerChild::RunFrameRequestCallbacks()
 {
   TimeStamp nowTime = TimeStamp::Now();
   mozilla::TimeDuration duration = nowTime - mStartTimeStamp;
   DOMHighResTimeStamp timeStamp = duration.ToMilliseconds();
 
 
--- a/gfx/vr/ipc/VRManagerChild.h
+++ b/gfx/vr/ipc/VRManagerChild.h
@@ -109,17 +109,17 @@ protected:
   virtual bool DeallocPVRLayerChild(PVRLayerChild* actor) override;
 
   virtual bool RecvUpdateDisplayInfo(nsTArray<VRDisplayInfo>&& aDisplayUpdates) override;
 
   virtual bool RecvParentAsyncMessages(InfallibleTArray<AsyncParentMessageData>&& aMessages) override;
 
   virtual bool RecvNotifyVSync() override;
   virtual bool RecvNotifyVRVSync(const uint32_t& aDisplayID) override;
-
+  virtual bool RecvGamepadUpdate(const GamepadChangeEvent& aGamepadEvent) override;
 
   // ShmemAllocator
 
   virtual bool AllocShmem(size_t aSize,
                           ipc::SharedMemory::SharedMemoryType aType,
                           ipc::Shmem* aShmem) override;
 
   virtual bool AllocUnsafeShmem(size_t aSize,
--- a/gfx/vr/ipc/VRMessageUtils.h
+++ b/gfx/vr/ipc/VRMessageUtils.h
@@ -154,11 +154,40 @@ struct ParamTraits<mozilla::gfx::VRField
         !ReadParam(aMsg, aIter, &(aResult->leftDegrees))) {
       return false;
     }
 
     return true;
   }
 };
 
+template <>
+struct ParamTraits<mozilla::gfx::VRControllerInfo>
+{
+  typedef mozilla::gfx::VRControllerInfo paramType;
+
+  static void Write(Message* aMsg, const paramType& aParam)
+  {
+    WriteParam(aMsg, aParam.mType);
+    WriteParam(aMsg, aParam.mControllerID);
+    WriteParam(aMsg, aParam.mControllerName);
+    WriteParam(aMsg, aParam.mMappingType);
+    WriteParam(aMsg, aParam.mNumButtons);
+    WriteParam(aMsg, aParam.mNumAxes);
+  }
+
+  static bool Read(const Message* aMsg, PickleIterator* aIter, paramType* aResult)
+  {
+    if (!ReadParam(aMsg, aIter, &(aResult->mType)) ||
+        !ReadParam(aMsg, aIter, &(aResult->mControllerID)) ||
+        !ReadParam(aMsg, aIter, &(aResult->mControllerName)) ||
+        !ReadParam(aMsg, aIter, &(aResult->mMappingType)) ||
+        !ReadParam(aMsg, aIter, &(aResult->mNumButtons)) ||
+        !ReadParam(aMsg, aIter, &(aResult->mNumAxes))) {
+      return false;
+    }
+
+    return true;
+  }
+};
 } // namespace IPC
 
 #endif // mozilla_gfx_vr_VRMessageUtils_h
--- a/gfx/vr/moz.build
+++ b/gfx/vr/moz.build
@@ -11,16 +11,17 @@ EXPORTS += [
     'ipc/VRManagerParent.h',
     'ipc/VRMessageUtils.h',
     'VRDisplayClient.h',
     'VRDisplayPresentation.h',
     'VRManager.h',
 ]
 
 LOCAL_INCLUDES += [
+    '/dom/base',
     '/gfx/layers/d3d11',
     '/gfx/thebes',
 ]
 
 UNIFIED_SOURCES += [
     'gfxVR.cpp',
     'gfxVROpenVR.cpp',
     'gfxVROSVR.cpp',