Bug 1627141 - Implement XRInputSourcesChangeEvent. r=kip

Differential Revision: https://phabricator.services.mozilla.com/D69483

--HG--
extra : moz-landing-system : lando
This commit is contained in:
Daosheng Mu 2020-04-08 04:39:01 +00:00
parent 0a58c515ed
commit fdf9039810
3 changed files with 62 additions and 5 deletions

View File

@ -6,6 +6,7 @@
#include "mozilla/dom/XRInputSourceArray.h"
#include "mozilla/dom/XRSession.h"
#include "mozilla/dom/XRInputSourcesChangeEvent.h"
namespace mozilla {
namespace dom {
@ -35,11 +36,21 @@ void XRInputSourceArray::Update(XRSession* aSession) {
return;
}
XRInputSourcesChangeEventInit addInit;
nsTArray<RefPtr<XRInputSource>> removedInputs;
for (int32_t i = 0; i < gfx::kVRControllerMaxCount; ++i) {
const gfx::VRControllerState& controllerState = displayClient->GetDisplayInfo().mControllerState[i];
if (controllerState.controllerName[0] == '\0') {
break; // We would not have an empty slot before others.
// Checking if exising controllers need to be removed.
for (auto& input : mInputSources) {
if (input->GetIndex() == i) {
removedInputs.AppendElement(input);
break;
}
}
continue;
}
bool found = false;
RefPtr<XRInputSource> inputSource = nullptr;
for (auto& input : mInputSources) {
@ -55,18 +66,60 @@ void XRInputSourceArray::Update(XRSession* aSession) {
inputSource = new XRInputSource(mParent);
inputSource->Setup(aSession, i);
mInputSources.AppendElement(inputSource);
addInit.mBubbles = false;
addInit.mCancelable = false;
addInit.mSession = aSession;
addInit.mAdded.AppendElement(*inputSource, mozilla::fallible);
}
// If added, updating the current controller states.
if (inputSource) {
inputSource->Update(aSession);
}
}
// Send `inputsourceschange` for new controllers.
if (addInit.mAdded.Length()) {
RefPtr<XRInputSourcesChangeEvent> event = XRInputSourcesChangeEvent::Constructor(aSession,
NS_LITERAL_STRING("inputsourceschange"), addInit);
event->SetTrusted(true);
aSession->DispatchEvent(*event);
}
// If there's a controller is removed, dispatch `inputsourceschange`.
if (removedInputs.Length()) {
DispatchInputSourceRemovedEvent(removedInputs, aSession);
}
for (auto& input: removedInputs) {
mInputSources.RemoveElement(input);
}
}
void XRInputSourceArray::Clear() {
for (auto& input: mInputSources) {
void XRInputSourceArray::DispatchInputSourceRemovedEvent(
const nsTArray<RefPtr<XRInputSource>>& aInputs, XRSession* aSession) {
XRInputSourcesChangeEventInit init;
for (auto& input: aInputs) {
input->SetGamepadIsConnected(false);
init.mBubbles = false;
init.mCancelable = false;
init.mSession = aSession;
init.mRemoved.AppendElement(*input, mozilla::fallible);
}
if (init.mRemoved.Length()) {
RefPtr<XRInputSourcesChangeEvent> event = XRInputSourcesChangeEvent::Constructor(aSession,
NS_LITERAL_STRING("inputsourceschange"), init);
event->SetTrusted(true);
aSession->DispatchEvent(*event);
}
}
void XRInputSourceArray::Clear(XRSession* aSession) {
DispatchInputSourceRemovedEvent(mInputSources, aSession);
mInputSources.Clear();
}

View File

@ -36,11 +36,15 @@ class XRInputSourceArray final : public nsISupports, public nsWrapperCache {
uint32_t Length();
void Setup(XRSession* aSession, RefPtr<gfx::VRDisplayClient> aDisplayClient);
void Update(XRSession* aSession);
void Clear();
void Clear(XRSession* aSession);
protected:
virtual ~XRInputSourceArray() = default;
private:
void DispatchInputSourceRemovedEvent(const nsTArray<RefPtr<XRInputSource>>& aInputs,
XRSession* aSession);
nsCOMPtr<nsISupports> mParent;
nsTArray<RefPtr<XRInputSource>> mInputSources;
};

View File

@ -401,7 +401,7 @@ void XRSession::Shutdown() {
void XRSession::ExitPresentInternal() {
if (mInputSources) {
mInputSources->Clear();
mInputSources->Clear(this);
}
if (mDisplayClient) {
mDisplayClient->SessionEnded(this);