diff options
Diffstat (limited to 'gfx/layers/apz/util/ContentProcessController.cpp')
-rw-r--r-- | gfx/layers/apz/util/ContentProcessController.cpp | 207 |
1 files changed, 207 insertions, 0 deletions
diff --git a/gfx/layers/apz/util/ContentProcessController.cpp b/gfx/layers/apz/util/ContentProcessController.cpp new file mode 100644 index 000000000..eccd4179f --- /dev/null +++ b/gfx/layers/apz/util/ContentProcessController.cpp @@ -0,0 +1,207 @@ +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim: set sw=4 ts=8 et 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 "ContentProcessController.h" + +#include "mozilla/dom/TabChild.h" +#include "mozilla/layers/APZCCallbackHelper.h" +#include "mozilla/layers/APZChild.h" + +#include "InputData.h" // for InputData + +namespace mozilla { +namespace layers { + +/** + * There are cases where we try to create the APZChild before the corresponding + * TabChild has been created, we use an observer for the "tab-child-created" + * topic to set the TabChild in the APZChild when it has been created. + */ +class TabChildCreatedObserver : public nsIObserver +{ +public: + TabChildCreatedObserver(ContentProcessController* aController, const dom::TabId& aTabId) + : mController(aController), + mTabId(aTabId) + {} + + NS_DECL_ISUPPORTS + NS_DECL_NSIOBSERVER + +private: + virtual ~TabChildCreatedObserver() + {} + + // TabChildCreatedObserver is owned by mController, and mController outlives its + // TabChildCreatedObserver, so the raw pointer is fine. + ContentProcessController* mController; + dom::TabId mTabId; +}; + +NS_IMPL_ISUPPORTS(TabChildCreatedObserver, nsIObserver) + +NS_IMETHODIMP +TabChildCreatedObserver::Observe(nsISupports* aSubject, + const char* aTopic, + const char16_t* aData) +{ + MOZ_ASSERT(strcmp(aTopic, "tab-child-created") == 0); + + nsCOMPtr<nsITabChild> tabChild(do_QueryInterface(aSubject)); + NS_ENSURE_TRUE(tabChild, NS_ERROR_FAILURE); + + dom::TabChild* browser = static_cast<dom::TabChild*>(tabChild.get()); + + if (browser->GetTabId() == mTabId) { + mController->SetBrowser(browser); + } + return NS_OK; +} + +APZChild* +ContentProcessController::Create(const dom::TabId& aTabId) +{ + RefPtr<dom::TabChild> browser = dom::TabChild::FindTabChild(aTabId); + + ContentProcessController* controller = new ContentProcessController(); + + nsAutoPtr<APZChild> apz(new APZChild(controller)); + + if (browser) { + + controller->SetBrowser(browser); + + } else { + + RefPtr<TabChildCreatedObserver> observer = + new TabChildCreatedObserver(controller, aTabId); + nsCOMPtr<nsIObserverService> os = services::GetObserverService(); + if (!os || + NS_FAILED(os->AddObserver(observer, "tab-child-created", false))) { + return nullptr; + } + controller->SetObserver(observer); + + } + + return apz.forget(); +} + +ContentProcessController::ContentProcessController() + : mBrowser(nullptr) +{ +} +ContentProcessController::~ContentProcessController() +{ + if (mObserver) { + nsCOMPtr<nsIObserverService> os = services::GetObserverService(); + os->RemoveObserver(mObserver, "tab-child-created"); + } +} + +void +ContentProcessController::SetObserver(nsIObserver* aObserver) +{ + MOZ_ASSERT(!mBrowser); + mObserver = aObserver; +} + +void +ContentProcessController::SetBrowser(dom::TabChild* aBrowser) +{ + MOZ_ASSERT(!mBrowser); + mBrowser = aBrowser; + + if (mObserver) { + nsCOMPtr<nsIObserverService> os = services::GetObserverService(); + os->RemoveObserver(mObserver, "tab-child-created"); + mObserver = nullptr; + } +} +void +ContentProcessController::RequestContentRepaint(const FrameMetrics& aFrameMetrics) +{ + if (mBrowser) { + mBrowser->UpdateFrame(aFrameMetrics); + } +} + +void +ContentProcessController::HandleTap( + TapType aType, + const LayoutDevicePoint& aPoint, + Modifiers aModifiers, + const ScrollableLayerGuid& aGuid, + uint64_t aInputBlockId) +{ + // This should never get called + MOZ_ASSERT(false); +} + +void +ContentProcessController::NotifyPinchGesture( + PinchGestureInput::PinchGestureType aType, + const ScrollableLayerGuid& aGuid, + LayoutDeviceCoord aSpanChange, + Modifiers aModifiers) +{ + // This should never get called + MOZ_ASSERT_UNREACHABLE("Unexpected message to content process"); +} + +void +ContentProcessController::NotifyAPZStateChange( + const ScrollableLayerGuid& aGuid, + APZStateChange aChange, + int aArg) +{ + if (mBrowser) { + mBrowser->NotifyAPZStateChange(aGuid.mScrollId, aChange, aArg); + } +} + +void +ContentProcessController::NotifyMozMouseScrollEvent( + const FrameMetrics::ViewID& aScrollId, + const nsString& aEvent) +{ + if (mBrowser) { + APZCCallbackHelper::NotifyMozMouseScrollEvent(aScrollId, aEvent); + } +} + +void +ContentProcessController::NotifyFlushComplete() +{ + if (mBrowser) { + nsCOMPtr<nsIPresShell> shell; + if (nsCOMPtr<nsIDocument> doc = mBrowser->GetDocument()) { + shell = doc->GetShell(); + } + APZCCallbackHelper::NotifyFlushComplete(shell.get()); + } +} + +void +ContentProcessController::PostDelayedTask(already_AddRefed<Runnable> aRunnable, int aDelayMs) +{ + MOZ_ASSERT_UNREACHABLE("ContentProcessController should only be used remotely."); +} + +bool +ContentProcessController::IsRepaintThread() +{ + return NS_IsMainThread(); +} + +void +ContentProcessController::DispatchToRepaintThread(already_AddRefed<Runnable> aTask) +{ + NS_DispatchToMainThread(Move(aTask)); +} + +} // namespace layers +} // namespace mozilla |