ipc::IPCResult DocAccessibleParent::AddChildDoc(DocAccessibleParent* aChildDoc, uint64_t aParentID, bool aCreating) { // We do not use GetAccessible here because we want to be sure to not get the // document it self. ProxyEntry* e = mAccessibles.GetEntry(aParentID); if (!e) { return IPC_FAIL(this, "binding to nonexistant proxy!"); } ProxyAccessible* outerDoc = e->mProxy; MOZ_ASSERT(outerDoc); // OuterDocAccessibles are expected to only have a document as a child. // However for compatibility we tolerate replacing one document with another // here. if (outerDoc->ChildrenCount() > 1 || (outerDoc->ChildrenCount() == 1 && !outerDoc->ChildAt(0)->IsDoc())) { return IPC_FAIL(this, "binding to proxy that can't be a outerDoc!"); } aChildDoc->SetParent(outerDoc); outerDoc->SetChildDoc(aChildDoc); mChildDocs.AppendElement(aChildDoc->mActorID); aChildDoc->mParentDoc = mActorID; if (aCreating) { ProxyCreated(aChildDoc, Interfaces::DOCUMENT | Interfaces::HYPERTEXT); } return IPC_OK(); }
mozilla::ipc::IPCResult nsIContentChild::RecvPBrowserConstructor(PBrowserChild* aActor, const TabId& aTabId, const TabId& aSameTabGroupAs, const IPCTabContext& aContext, const uint32_t& aChromeFlags, const ContentParentId& aCpID, const bool& aIsForBrowser) { // This runs after AllocPBrowserChild() returns and the IPC machinery for this // PBrowserChild has been set up. auto tabChild = static_cast<TabChild*>(static_cast<TabChild*>(aActor)); if (NS_WARN_IF(NS_FAILED(tabChild->Init()))) { return IPC_FAIL(tabChild, "TabChild::Init failed"); } nsCOMPtr<nsIObserverService> os = services::GetObserverService(); if (os) { os->NotifyObservers(static_cast<nsITabChild*>(tabChild), "tab-child-created", nullptr); } return IPC_OK(); }
mozilla::ipc::IPCResult DocAccessibleParent::RecvGetWindowedPluginIAccessible( const WindowsHandle& aHwnd, IAccessibleHolder* aPluginCOMProxy) { #if defined(MOZ_CONTENT_SANDBOX) // We don't actually want the accessible object for aHwnd, but rather the // one that belongs to its child (see HTMLWin32ObjectAccessible). HWND childWnd = ::GetWindow(reinterpret_cast<HWND>(aHwnd), GW_CHILD); if (!childWnd) { // We're seeing this in the wild - the plugin is windowed but we no longer // have a window. return IPC_OK(); } IAccessible* rawAccPlugin = nullptr; HRESULT hr = ::AccessibleObjectFromWindow(childWnd, OBJID_WINDOW, IID_IAccessible, (void**)&rawAccPlugin); if (FAILED(hr)) { // This might happen if the plugin doesn't handle WM_GETOBJECT properly. // We should not consider that a failure. return IPC_OK(); } aPluginCOMProxy->Set(IAccessibleHolder::COMPtrType(rawAccPlugin)); return IPC_OK(); #else return IPC_FAIL(this, "Message unsupported in this build configuration"); #endif }
mozilla::ipc::IPCResult VRManagerParent::RecvCreateVRServiceTestController(const nsCString& aID, const uint32_t& aPromiseID) { uint32_t controllerIdx = 0; nsTArray<VRControllerInfo> controllerInfoArray; impl::VRControllerPuppet* controllerPuppet = nullptr; VRManager* vm = VRManager::Get(); // Get VRControllerPuppet from VRManager vm->GetVRControllerInfo(controllerInfoArray); for (auto& controllerInfo : controllerInfoArray) { if (controllerInfo.GetType() == VRDeviceType::Puppet) { if (controllerIdx == mControllerTestID) { controllerPuppet = static_cast<impl::VRControllerPuppet*>( vm->GetController(controllerInfo.GetControllerID()).get()); break; } ++controllerIdx; } } MOZ_ASSERT(controllerPuppet); MOZ_ASSERT(mControllerTestID < 2); // We have only two controllers in VRSystemManagerPuppet. if (!mVRControllerTests.Get(mControllerTestID, nullptr)) { mVRControllerTests.Put(mControllerTestID, controllerPuppet); } if (SendReplyCreateVRServiceTestController(aID, aPromiseID, mControllerTestID)) { ++mControllerTestID; return IPC_OK(); } return IPC_FAIL(this, "SendReplyCreateVRServiceTestController fail"); }
mozilla::ipc::IPCResult DocAccessibleParent::RecvBindChildDoc(PDocAccessibleParent* aChildDoc, const uint64_t& aID) { // One document should never directly be the child of another. // We should always have at least an outer doc accessible in between. MOZ_ASSERT(aID); if (!aID) return IPC_FAIL(this, "ID is 0!"); if (mShutdown) { return IPC_OK(); } MOZ_ASSERT(CheckDocTree()); auto childDoc = static_cast<DocAccessibleParent*>(aChildDoc); childDoc->Unbind(); ipc::IPCResult result = AddChildDoc(childDoc, aID, false); MOZ_ASSERT(result); MOZ_ASSERT(CheckDocTree()); #ifdef DEBUG if (!result) { return result; } #else result = IPC_OK(); #endif return result; }
mozilla::ipc::IPCResult VRManagerParent::RecvCreateVRServiceTestDisplay(const nsCString& aID, const uint32_t& aPromiseID) { nsTArray<VRDisplayInfo> displayInfoArray; impl::VRDisplayPuppet* displayPuppet = nullptr; VRManager* vm = VRManager::Get(); vm->RefreshVRDisplays(); // Get VRDisplayPuppet from VRManager vm->GetVRDisplayInfo(displayInfoArray); for (auto& displayInfo : displayInfoArray) { if (displayInfo.GetType() == VRDeviceType::Puppet) { displayPuppet = static_cast<impl::VRDisplayPuppet*>( vm->GetDisplay(displayInfo.GetDisplayID()).get()); break; } } MOZ_ASSERT(displayPuppet); MOZ_ASSERT(!mDisplayTestID); // We have only one display in VRSystemManagerPuppet. if (!mVRDisplayTests.Get(mDisplayTestID, nullptr)) { mVRDisplayTests.Put(mDisplayTestID, displayPuppet); } if (SendReplyCreateVRServiceTestDisplay(aID, aPromiseID, mDisplayTestID)) { return IPC_OK(); } return IPC_FAIL(this, "SendReplyCreateVRServiceTestController fail"); }
mozilla::ipc::IPCResult DocAccessibleParent::RecvHideEvent(const uint64_t& aRootID, const bool& aFromUser) { if (mShutdown) return IPC_OK(); MOZ_ASSERT(CheckDocTree()); // We shouldn't actually need this because mAccessibles shouldn't have an // entry for the document itself, but it doesn't hurt to be explicit. if (!aRootID) { return IPC_FAIL(this, "Trying to hide entire document?"); } ProxyEntry* rootEntry = mAccessibles.GetEntry(aRootID); if (!rootEntry) { NS_ERROR("invalid root being removed!"); return IPC_OK(); } ProxyAccessible* root = rootEntry->mProxy; if (!root) { NS_ERROR("invalid root being removed!"); return IPC_OK(); } ProxyAccessible* parent = root->Parent(); ProxyShowHideEvent(root, parent, false, aFromUser); RefPtr<xpcAccHideEvent> event = nullptr; if (nsCoreUtils::AccEventObserversExist()) { uint32_t type = nsIAccessibleEvent::EVENT_HIDE; xpcAccessibleGeneric* xpcAcc = GetXPCAccessible(root); xpcAccessibleGeneric* xpcParent = GetXPCAccessible(parent); ProxyAccessible* next = root->NextSibling(); xpcAccessibleGeneric* xpcNext = next ? GetXPCAccessible(next) : nullptr; ProxyAccessible* prev = root->PrevSibling(); xpcAccessibleGeneric* xpcPrev = prev ? GetXPCAccessible(prev) : nullptr; xpcAccessibleDocument* doc = GetAccService()->GetXPCDocument(this); nsIDOMNode* node = nullptr; event = new xpcAccHideEvent(type, xpcAcc, doc, node, aFromUser, xpcParent, xpcNext, xpcPrev); } parent->RemoveChild(root); root->Shutdown(); MOZ_ASSERT(CheckDocTree()); if (event) { nsCoreUtils::DispatchAccEvent(Move(event)); } return IPC_OK(); }
mozilla::ipc::IPCResult VRManagerParent::RecvCreateVRServiceTestDisplay(const nsCString& aID, const uint32_t& aPromiseID) { VRManager* vm = VRManager::Get(); VRSystemManagerPuppet* puppetManager = vm->GetPuppetManager(); uint32_t deviceID = puppetManager->CreateTestDisplay(); if (SendReplyCreateVRServiceTestDisplay(aID, aPromiseID, deviceID)) { return IPC_OK(); } return IPC_FAIL(this, "SendReplyCreateVRServiceTestController fail"); }
mozilla::ipc::IPCResult VRManagerParent::RecvCreateVRServiceTestController(const nsCString& aID, const uint32_t& aPromiseID) { uint32_t controllerIdx = 1; // ID's are 1 based nsTArray<VRControllerInfo> controllerInfoArray; impl::VRControllerPuppet* controllerPuppet = nullptr; VRManager* vm = VRManager::Get(); /** * When running headless mochitests on some of our automated test * infrastructure, 2d display vsyncs are not always generated. * In this case, the test controllers can't be created immediately * after the VR display was created as the state of the VR displays * are updated during vsync. * To workaround, we produce a vsync manually. */ vm->NotifyVsync(TimeStamp::Now()); // Get VRControllerPuppet from VRManager vm->GetVRControllerInfo(controllerInfoArray); for (auto& controllerInfo : controllerInfoArray) { if (controllerInfo.GetType() == VRDeviceType::Puppet) { if (controllerIdx == mControllerTestID) { controllerPuppet = static_cast<impl::VRControllerPuppet*>( vm->GetController(controllerInfo.GetControllerID()).get()); break; } ++controllerIdx; } } // We might not have a controllerPuppet if the test did // not create a VR display first. if (!controllerPuppet) { // We send a device ID of "0" to indicate failure if (SendReplyCreateVRServiceTestController(aID, aPromiseID, 0)) { return IPC_OK(); } } else { if (!mVRControllerTests.Get(mControllerTestID, nullptr)) { mVRControllerTests.Put(mControllerTestID, controllerPuppet); } if (SendReplyCreateVRServiceTestController(aID, aPromiseID, mControllerTestID)) { ++mControllerTestID; return IPC_OK(); } } return IPC_FAIL(this, "SendReplyCreateVRServiceTestController fail"); }
mozilla::ipc::IPCResult DocAccessibleParent::RecvRoleChangedEvent(const uint32_t& aRole) { if (mShutdown) { return IPC_OK(); } if (aRole > roles::LAST_ROLE) { return IPC_FAIL(this, "Child sent bad role in RoleChangedEvent"); } mRole = static_cast<a11y::role>(aRole); return IPC_OK(); }
mozilla::ipc::IPCResult UDPSocketParent::RecvOutgoingData(const UDPData& aData, const UDPSocketAddr& aAddr) { if (!mSocket) { NS_WARNING("sending socket is closed"); FireInternalError(__LINE__); return IPC_OK(); } nsresult rv; if (mFilter) { if (aAddr.type() != UDPSocketAddr::TNetAddr) { return IPC_OK(); } // TODO, Packet filter doesn't support input stream yet. if (aData.type() != UDPData::TArrayOfuint8_t) { return IPC_OK(); } bool allowed; const InfallibleTArray<uint8_t>& data(aData.get_ArrayOfuint8_t()); rv = mFilter->FilterPacket(&aAddr.get_NetAddr(), data.Elements(), data.Length(), nsISocketFilter::SF_OUTGOING, &allowed); // Sending unallowed data, kill content. if (NS_WARN_IF(NS_FAILED(rv)) || !allowed) { return IPC_FAIL(this, "Content tried to send non STUN packet"); } } switch(aData.type()) { case UDPData::TArrayOfuint8_t: Send(aData.get_ArrayOfuint8_t(), aAddr); break; case UDPData::TIPCStream: Send(aData.get_IPCStream(), aAddr); break; default: MOZ_ASSERT(false, "Invalid data type!"); return IPC_OK(); } return IPC_OK(); }
mozilla::ipc::IPCResult DocAccessibleParent::RecvShowEvent(const ShowEventData& aData, const bool& aFromUser) { if (mShutdown) return IPC_OK(); MOZ_ASSERT(CheckDocTree()); if (aData.NewTree().IsEmpty()) { NS_ERROR("no children being added"); return IPC_FAIL_NO_REASON(this); } ProxyAccessible* parent = GetAccessible(aData.ID()); // XXX This should really never happen, but sometimes we fail to fire the // required show events. if (!parent) { NS_ERROR("adding child to unknown accessible"); #ifdef DEBUG return IPC_FAIL(this, "unknown parent accessible"); #else return IPC_OK(); #endif } uint32_t newChildIdx = aData.Idx(); if (newChildIdx > parent->ChildrenCount()) { NS_ERROR("invalid index to add child at"); #ifdef DEBUG return IPC_FAIL(this, "invalid index"); #else return IPC_OK(); #endif } uint32_t consumed = AddSubtree(parent, aData.NewTree(), 0, newChildIdx); MOZ_ASSERT(consumed == aData.NewTree().Length()); // XXX This shouldn't happen, but if we failed to add children then the below // is pointless and can crash. if (!consumed) { return IPC_FAIL(this, "failed to add children"); } #ifdef DEBUG for (uint32_t i = 0; i < consumed; i++) { uint64_t id = aData.NewTree()[i].ID(); MOZ_ASSERT(mAccessibles.GetEntry(id)); } #endif MOZ_ASSERT(CheckDocTree()); ProxyAccessible* target = parent->ChildAt(newChildIdx); ProxyShowHideEvent(target, parent, true, aFromUser); if (!nsCoreUtils::AccEventObserversExist()) { return IPC_OK(); } uint32_t type = nsIAccessibleEvent::EVENT_SHOW; xpcAccessibleGeneric* xpcAcc = GetXPCAccessible(target); xpcAccessibleDocument* doc = GetAccService()->GetXPCDocument(this); nsIDOMNode* node = nullptr; RefPtr<xpcAccEvent> event = new xpcAccEvent(type, xpcAcc, doc, node, aFromUser); nsCoreUtils::DispatchAccEvent(Move(event)); return IPC_OK(); }