2014-08-08 14:42:20 -07:00
|
|
|
/* -*- Mode: c++; c-basic-offset: 4; tab-width: 20; indent-tabs-mode: nil; -*-
|
|
|
|
* 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 "APZCCallbackHandler.h"
|
|
|
|
#include "mozilla/layers/APZCCallbackHelper.h"
|
|
|
|
#include "mozilla/layers/APZCTreeManager.h"
|
|
|
|
#include "nsAppShell.h"
|
|
|
|
#include "nsLayoutUtils.h"
|
|
|
|
#include "nsPrintfCString.h"
|
|
|
|
#include "nsThreadUtils.h"
|
|
|
|
#include "base/message_loop.h"
|
|
|
|
#include "nsWindow.h"
|
|
|
|
#include "nsIInterfaceRequestorUtils.h"
|
|
|
|
#include "AndroidBridge.h"
|
2014-08-18 07:44:50 -07:00
|
|
|
#include "nsIContent.h"
|
2014-08-08 14:42:20 -07:00
|
|
|
|
|
|
|
using mozilla::layers::APZCCallbackHelper;
|
2014-08-08 15:15:37 -07:00
|
|
|
using mozilla::layers::APZCTreeManager;
|
2014-08-08 14:42:20 -07:00
|
|
|
using mozilla::layers::FrameMetrics;
|
|
|
|
using mozilla::layers::ScrollableLayerGuid;
|
|
|
|
|
|
|
|
namespace mozilla {
|
|
|
|
namespace widget {
|
|
|
|
namespace android {
|
|
|
|
|
|
|
|
StaticRefPtr<APZCCallbackHandler> APZCCallbackHandler::sInstance;
|
|
|
|
|
|
|
|
NativePanZoomController*
|
|
|
|
APZCCallbackHandler::SetNativePanZoomController(jobject obj)
|
|
|
|
{
|
|
|
|
NativePanZoomController* old = mNativePanZoomController;
|
|
|
|
mNativePanZoomController = NativePanZoomController::Wrap(obj);
|
|
|
|
return old;
|
|
|
|
}
|
|
|
|
|
2014-08-08 15:15:37 -07:00
|
|
|
void
|
|
|
|
APZCCallbackHandler::NotifyDefaultPrevented(const ScrollableLayerGuid& aGuid,
|
|
|
|
bool aDefaultPrevented)
|
|
|
|
{
|
2014-08-08 15:15:38 -07:00
|
|
|
if (!AndroidBridge::IsJavaUiThread()) {
|
2014-08-08 15:15:37 -07:00
|
|
|
// The notification must reach the APZ on the Java UI thread (aka the
|
|
|
|
// APZ "controller" thread) but we get it from the Gecko thread, so we
|
|
|
|
// have to throw it onto the other thread.
|
|
|
|
AndroidBridge::Bridge()->PostTaskToUiThread(NewRunnableMethod(
|
|
|
|
this, &APZCCallbackHandler::NotifyDefaultPrevented,
|
|
|
|
aGuid, aDefaultPrevented), 0);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2014-08-08 15:15:38 -07:00
|
|
|
MOZ_ASSERT(AndroidBridge::IsJavaUiThread());
|
2014-08-08 15:15:37 -07:00
|
|
|
APZCTreeManager* controller = nsWindow::GetAPZCTreeManager();
|
|
|
|
if (controller) {
|
|
|
|
controller->ContentReceivedTouch(aGuid, aDefaultPrevented);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2014-08-08 14:42:20 -07:00
|
|
|
nsIDOMWindowUtils*
|
|
|
|
APZCCallbackHandler::GetDOMWindowUtils()
|
|
|
|
{
|
|
|
|
nsIAndroidBrowserApp* browserApp = nullptr;
|
|
|
|
if (!nsAppShell::gAppShell) {
|
|
|
|
return nullptr;
|
|
|
|
}
|
|
|
|
nsAppShell::gAppShell->GetBrowserApp(&browserApp);
|
|
|
|
if (!browserApp) {
|
|
|
|
return nullptr;
|
|
|
|
}
|
|
|
|
nsIBrowserTab* tab = nullptr;
|
|
|
|
if (browserApp->GetSelectedTab(&tab) != NS_OK) {
|
|
|
|
return nullptr;
|
|
|
|
}
|
|
|
|
nsIDOMWindow* window = nullptr;
|
|
|
|
if (tab->GetWindow(&window) != NS_OK) {
|
|
|
|
return nullptr;
|
|
|
|
}
|
|
|
|
nsCOMPtr<nsIDOMWindowUtils> utils = do_GetInterface(window);
|
|
|
|
return utils.get();
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
APZCCallbackHandler::RequestContentRepaint(const FrameMetrics& aFrameMetrics)
|
|
|
|
{
|
|
|
|
if (!NS_IsMainThread()) {
|
|
|
|
NS_DispatchToMainThread(NS_NewRunnableMethodWithArg<FrameMetrics>(
|
|
|
|
this, &APZCCallbackHandler::RequestContentRepaint, aFrameMetrics));
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
MOZ_ASSERT(NS_IsMainThread());
|
|
|
|
MOZ_ASSERT(aFrameMetrics.GetScrollId() != FrameMetrics::NULL_SCROLL_ID);
|
|
|
|
|
2014-08-23 16:55:55 -07:00
|
|
|
if (aFrameMetrics.GetIsRoot()) {
|
2014-08-08 14:42:20 -07:00
|
|
|
nsIDOMWindowUtils* utils = GetDOMWindowUtils();
|
|
|
|
if (utils && APZCCallbackHelper::HasValidPresShellId(utils, aFrameMetrics)) {
|
|
|
|
FrameMetrics metrics = aFrameMetrics;
|
|
|
|
APZCCallbackHelper::UpdateRootFrame(utils, metrics);
|
|
|
|
APZCCallbackHelper::UpdateCallbackTransform(aFrameMetrics, metrics);
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
// aFrameMetrics.mIsRoot is false, so we are trying to update a subframe.
|
|
|
|
// This requires special handling.
|
|
|
|
nsCOMPtr<nsIContent> content = nsLayoutUtils::FindContentFor(aFrameMetrics.GetScrollId());
|
|
|
|
if (content) {
|
|
|
|
FrameMetrics newSubFrameMetrics(aFrameMetrics);
|
|
|
|
APZCCallbackHelper::UpdateSubFrame(content, newSubFrameMetrics);
|
|
|
|
APZCCallbackHelper::UpdateCallbackTransform(aFrameMetrics, newSubFrameMetrics);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
APZCCallbackHandler::AcknowledgeScrollUpdate(const FrameMetrics::ViewID& aScrollId,
|
|
|
|
const uint32_t& aScrollGeneration)
|
|
|
|
{
|
|
|
|
APZCCallbackHelper::AcknowledgeScrollUpdate(aScrollId, aScrollGeneration);
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
APZCCallbackHandler::HandleDoubleTap(const CSSPoint& aPoint,
|
|
|
|
int32_t aModifiers,
|
|
|
|
const mozilla::layers::ScrollableLayerGuid& aGuid)
|
|
|
|
{
|
2014-08-26 09:45:04 -07:00
|
|
|
CSSIntPoint point = RoundedToInt(aPoint);
|
|
|
|
nsCString data = nsPrintfCString("{ \"x\": %d, \"y\": %d }", point.x, point.y);
|
2014-08-08 14:42:20 -07:00
|
|
|
nsAppShell::gAppShell->PostEvent(AndroidGeckoEvent::MakeBroadcastEvent(
|
|
|
|
NS_LITERAL_CSTRING("Gesture:DoubleTap"), data));
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
APZCCallbackHandler::HandleSingleTap(const CSSPoint& aPoint,
|
|
|
|
int32_t aModifiers,
|
|
|
|
const mozilla::layers::ScrollableLayerGuid& aGuid)
|
|
|
|
{
|
|
|
|
// FIXME Send the modifier data to Gecko for use in mouse events.
|
2014-08-26 09:45:04 -07:00
|
|
|
CSSIntPoint point = RoundedToInt(aPoint);
|
|
|
|
nsCString data = nsPrintfCString("{ \"x\": %d, \"y\": %d }", point.x, point.y);
|
2014-08-08 14:42:20 -07:00
|
|
|
nsAppShell::gAppShell->PostEvent(AndroidGeckoEvent::MakeBroadcastEvent(
|
|
|
|
NS_LITERAL_CSTRING("Gesture:SingleTap"), data));
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
APZCCallbackHandler::HandleLongTap(const CSSPoint& aPoint,
|
|
|
|
int32_t aModifiers,
|
|
|
|
const mozilla::layers::ScrollableLayerGuid& aGuid)
|
|
|
|
{
|
|
|
|
// TODO send content response back to APZC
|
2014-08-26 09:45:04 -07:00
|
|
|
CSSIntPoint point = RoundedToInt(aPoint);
|
|
|
|
nsCString data = nsPrintfCString("{ \"x\": %d, \"y\": %d }", point.x, point.y);
|
2014-08-08 14:42:20 -07:00
|
|
|
nsAppShell::gAppShell->PostEvent(AndroidGeckoEvent::MakeBroadcastEvent(
|
|
|
|
NS_LITERAL_CSTRING("Gesture:LongPress"), data));
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
APZCCallbackHandler::HandleLongTapUp(const CSSPoint& aPoint,
|
|
|
|
int32_t aModifiers,
|
|
|
|
const mozilla::layers::ScrollableLayerGuid& aGuid)
|
|
|
|
{
|
|
|
|
HandleSingleTap(aPoint, aModifiers, aGuid);
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
APZCCallbackHandler::SendAsyncScrollDOMEvent(bool aIsRoot,
|
|
|
|
const CSSRect& aContentRect,
|
|
|
|
const CSSSize& aScrollableSize)
|
|
|
|
{
|
|
|
|
// no-op, we don't want to support this event on fennec, and we
|
|
|
|
// want to get rid of this entirely. See bug 898075.
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
APZCCallbackHandler::PostDelayedTask(Task* aTask, int aDelayMs)
|
|
|
|
{
|
|
|
|
AndroidBridge::Bridge()->PostTaskToUiThread(aTask, aDelayMs);
|
|
|
|
}
|
|
|
|
|
|
|
|
} // namespace android
|
|
|
|
} // namespace widget
|
|
|
|
} // namespace mozilla
|