Mypal/gfx/layers/apz/util/ContentProcessController.cpp

207 lines
5.4 KiB
C++

/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* 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