bug 727352 - don't use JSON for viewport meta data r=kats,mfinkle

This commit is contained in:
Brad Lassey 2012-09-12 23:47:08 +02:00
parent 98470da125
commit 2f969ba0da
8 changed files with 252 additions and 34 deletions

View File

@ -126,9 +126,6 @@ public class GeckoLayerClient
mRootLayer = new VirtualLayer(new IntSize(mView.getWidth(), mView.getHeight()));
mLayerRenderer = new LayerRenderer(mView);
registerEventListener("Viewport:Update");
registerEventListener("Viewport:PageSize");
registerEventListener("Viewport:CalculateDisplayPort");
registerEventListener("Checkerboard:Toggle");
mView.setListener(this);
@ -142,9 +139,6 @@ public class GeckoLayerClient
public void destroy() {
mPanZoomController.destroy();
unregisterEventListener("Viewport:Update");
unregisterEventListener("Viewport:PageSize");
unregisterEventListener("Viewport:CalculateDisplayPort");
unregisterEventListener("Checkerboard:Toggle");
}
@ -311,8 +305,7 @@ public class GeckoLayerClient
}
/** Viewport message handler. */
private void handleViewportMessage(JSONObject message, ViewportMessageType type) throws JSONException {
ViewportMetrics messageMetrics = new ViewportMetrics(message);
private DisplayPortMetrics handleViewportMessage(ViewportMetrics messageMetrics, ViewportMessageType type) {
synchronized (this) {
final ViewportMetrics newMetrics;
ImmutableViewportMetrics oldMetrics = getViewportMetrics();
@ -343,20 +336,30 @@ public class GeckoLayerClient
setViewportMetrics(newMetrics, type == ViewportMessageType.UPDATE);
mDisplayPort = DisplayPortCalculator.calculate(getViewportMetrics(), null);
}
mReturnDisplayPort = mDisplayPort;
return mDisplayPort;
}
public DisplayPortMetrics getDisplayPort(boolean pageSizeUpdate, boolean isBrowserContentDisplayed, int tabId, ViewportMetrics metrics) {
Tabs tabs = Tabs.getInstance();
if (tabs.isSelectedTab(tabs.getTab(tabId)) && isBrowserContentDisplayed) {
// for foreground tabs, send the viewport update unless the document
// displayed is different from the content document. In that case, just
// calculate the display port.
return handleViewportMessage(metrics, pageSizeUpdate ? ViewportMessageType.UPDATE : ViewportMessageType.PAGE_SIZE);
} else {
// for background tabs, request a new display port calculation, so that
// when we do switch to that tab, we have the correct display port and
// don't need to draw twice (once to allow the first-paint viewport to
// get to java, and again once java figures out the display port).
ImmutableViewportMetrics newMetrics = new ImmutableViewportMetrics(metrics);
return DisplayPortCalculator.calculate(newMetrics, null);
}
}
/** Implementation of GeckoEventResponder/GeckoEventListener. */
public void handleMessage(String event, JSONObject message) {
try {
if ("Viewport:Update".equals(event)) {
handleViewportMessage(message, ViewportMessageType.UPDATE);
} else if ("Viewport:PageSize".equals(event)) {
handleViewportMessage(message, ViewportMessageType.PAGE_SIZE);
} else if ("Viewport:CalculateDisplayPort".equals(event)) {
ImmutableViewportMetrics newMetrics = new ImmutableViewportMetrics(new ViewportMetrics(message));
mReturnDisplayPort = DisplayPortCalculator.calculate(newMetrics, null);
} else if ("Checkerboard:Toggle".equals(event)) {
if ("Checkerboard:Toggle".equals(event)) {
mView.setCheckerboardShouldShowChecks(message.getBoolean("value"));
}
} catch (JSONException e) {

View File

@ -77,6 +77,16 @@ public class ViewportMetrics {
mZoomFactor = zoom;
}
public ViewportMetrics(float x, float y, float width, float height,
float pageLeft, float pageTop, float pageRight, float pageBottom,
float cssPageLeft, float cssPageTop, float cssPageRight, float cssPageBottom,
float zoom) {
mPageRect = new RectF(pageLeft, pageTop, pageRight, pageBottom);
mCssPageRect = new RectF(cssPageLeft, cssPageTop, cssPageRight, cssPageBottom);
mViewportRect = new RectF(x, y, x + width, y + height);
mZoomFactor = zoom;
}
public PointF getOrigin() {
return new PointF(mViewportRect.left, mViewportRect.top);
}

View File

@ -2722,24 +2722,10 @@ Tab.prototype = {
},
sendViewportUpdate: function(aPageSizeUpdate) {
let message;
// for foreground tabs, send the viewport update unless the document
// displayed is different from the content document. In that case, just
// calculate the display port.
if (BrowserApp.selectedTab == this && BrowserApp.isBrowserContentDocumentDisplayed()) {
message = this.getViewport();
message.type = aPageSizeUpdate ? "Viewport:PageSize" : "Viewport:Update";
} else {
// for background tabs, request a new display port calculation, so that
// when we do switch to that tab, we have the correct display port and
// don't need to draw twice (once to allow the first-paint viewport to
// get to java, and again once java figures out the display port).
message = this.getViewport();
message.type = "Viewport:CalculateDisplayPort";
}
let displayPort = sendMessageToJava({ gecko: message });
let viewport = this.getViewport();
let displayPort = getBridge().getDisplayPort(aPageSizeUpdate, BrowserApp.isBrowserContentDocumentDisplayed(), this.id, viewport);
if (displayPort != null)
this.setDisplayPort(JSON.parse(displayPort));
this.setDisplayPort(displayPort);
},
handleEvent: function(aEvent) {

View File

@ -2519,6 +2519,24 @@ nsresult AndroidBridge::TakeScreenshot(nsIDOMWindow *window, int32_t srcX, int32
return NS_OK;
}
nsresult
nsAndroidBridge::GetDisplayPort(bool aPageSizeUpdate, bool aIsBrowserContentDisplayed, int32_t tabId, nsIAndroidViewport* metrics, nsIAndroidDisplayport** displayPort)
{
return AndroidBridge::Bridge()->GetDisplayPort(aPageSizeUpdate, aIsBrowserContentDisplayed, tabId, metrics, displayPort);
}
nsresult
AndroidBridge::GetDisplayPort(bool aPageSizeUpdate, bool aIsBrowserContentDisplayed, int32_t tabId, nsIAndroidViewport* metrics, nsIAndroidDisplayport** displayPort)
{
JNIEnv* env = GetJNIEnv();
if (!env || !mLayerClient)
return NS_OK;
AutoLocalJNIFrame jniFrame(env, 0);
mLayerClient->GetDisplayPort(&jniFrame, aPageSizeUpdate, aIsBrowserContentDisplayed, tabId, metrics, displayPort);
return NS_OK;
}
void
AndroidBridge::NotifyPaintedRect(float top, float left, float bottom, float right)
{

View File

@ -154,6 +154,7 @@ public:
static void NotifyIMEChange(const PRUnichar *aText, uint32_t aTextLen, int aStart, int aEnd, int aNewEnd);
nsresult TakeScreenshot(nsIDOMWindow *window, int32_t srcX, int32_t srcY, int32_t srcW, int32_t srcH, int32_t dstY, int32_t dstX, int32_t dstW, int32_t dstH, int32_t bufW, int32_t bufH, int32_t tabId, int32_t token, jobject buffer);
nsresult GetDisplayPort(bool aPageSizeUpdate, bool aIsBrowserContentDisplayed, int32_t tabId, nsIAndroidViewport* metrics, nsIAndroidDisplayport** displayPort);
static void NotifyPaintedRect(float top, float left, float bottom, float right);

View File

@ -5,6 +5,7 @@
#include "AndroidJavaWrappers.h"
#include "AndroidBridge.h"
#include "nsIAndroidBridge.h"
using namespace mozilla;
@ -55,6 +56,12 @@ jfieldID AndroidRect::jLeftField = 0;
jfieldID AndroidRect::jRightField = 0;
jfieldID AndroidRect::jTopField = 0;
jclass AndroidRectF::jRectClass = 0;
jfieldID AndroidRectF::jBottomField = 0;
jfieldID AndroidRectF::jLeftField = 0;
jfieldID AndroidRectF::jRightField = 0;
jfieldID AndroidRectF::jTopField = 0;
jclass AndroidLocation::jLocationClass = 0;
jmethodID AndroidLocation::jGetLatitudeMethod = 0;
jmethodID AndroidLocation::jGetLongitudeMethod = 0;
@ -65,12 +72,18 @@ jmethodID AndroidLocation::jGetSpeedMethod = 0;
jmethodID AndroidLocation::jGetTimeMethod = 0;
jclass AndroidGeckoLayerClient::jGeckoLayerClientClass = 0;
jclass AndroidGeckoLayerClient::jViewportClass = 0;
jclass AndroidGeckoLayerClient::jDisplayportClass = 0;
jmethodID AndroidGeckoLayerClient::jSetFirstPaintViewport = 0;
jmethodID AndroidGeckoLayerClient::jSetPageRect = 0;
jmethodID AndroidGeckoLayerClient::jSyncViewportInfoMethod = 0;
jmethodID AndroidGeckoLayerClient::jCreateFrameMethod = 0;
jmethodID AndroidGeckoLayerClient::jActivateProgramMethod = 0;
jmethodID AndroidGeckoLayerClient::jDeactivateProgramMethod = 0;
jmethodID AndroidGeckoLayerClient::jGetDisplayPort = 0;
jmethodID AndroidGeckoLayerClient::jViewportCtor = 0;
jfieldID AndroidGeckoLayerClient::jDisplayportPosition = 0;
jfieldID AndroidGeckoLayerClient::jDisplayportResolution = 0;
jclass AndroidLayerRendererFrame::jLayerRendererFrameClass = 0;
jmethodID AndroidLayerRendererFrame::jBeginDrawingMethod = 0;
@ -169,6 +182,7 @@ mozilla::InitAndroidJavaWrappers(JNIEnv *jEnv)
AndroidPoint::InitPointClass(jEnv);
AndroidLocation::InitLocationClass(jEnv);
AndroidRect::InitRectClass(jEnv);
AndroidRectF::InitRectFClass(jEnv);
AndroidGeckoLayerClient::InitGeckoLayerClientClass(jEnv);
AndroidLayerRendererFrame::InitLayerRendererFrameClass(jEnv);
AndroidViewTransform::InitViewTransformClass(jEnv);
@ -301,6 +315,19 @@ AndroidRect::InitRectClass(JNIEnv *jEnv)
jRightField = getField("right", "I");
}
void
AndroidRectF::InitRectFClass(JNIEnv *jEnv)
{
initInit();
jRectClass = getClassGlobalRef("android/graphics/RectF");
jBottomField = getField("bottom", "F");
jLeftField = getField("left", "F");
jTopField = getField("top", "F");
jRightField = getField("right", "F");
}
void
AndroidGeckoLayerClient::InitGeckoLayerClientClass(JNIEnv *jEnv)
{
@ -316,6 +343,15 @@ AndroidGeckoLayerClient::InitGeckoLayerClientClass(JNIEnv *jEnv)
jCreateFrameMethod = getMethod("createFrame", "()Lorg/mozilla/gecko/gfx/LayerRenderer$Frame;");
jActivateProgramMethod = getMethod("activateProgram", "()V");
jDeactivateProgramMethod = getMethod("deactivateProgram", "()V");
jGetDisplayPort = getMethod("getDisplayPort", "(ZZILorg/mozilla/gecko/gfx/ViewportMetrics;)Lorg/mozilla/gecko/gfx/DisplayPortMetrics;");
jViewportClass = GetClassGlobalRef(jEnv, "org/mozilla/gecko/gfx/ViewportMetrics");
jViewportCtor = GetMethodID(jEnv, jViewportClass, "<init>", "(FFFFFFFFFFFFF)V");
jDisplayportClass = GetClassGlobalRef(jEnv, "org/mozilla/gecko/gfx/DisplayPortMetrics");
jDisplayportPosition = GetFieldID(jEnv, jDisplayportClass, "mPosition", "Landroid/graphics/RectF;");
jDisplayportResolution = GetFieldID(jEnv, jDisplayportClass, "mResolution", "F");
#endif
}
@ -767,6 +803,79 @@ AndroidGeckoLayerClient::SyncViewportInfo(const nsIntRect& aDisplayPort, float a
aScaleX = aScaleY = viewTransform.GetScale(env);
}
jobject ConvertToJavaViewportMetrics(JNIEnv* env, nsIAndroidViewport* metrics) {
float x, y, width, height,
pageLeft, pageTop, pageRight, pageBottom,
cssPageLeft, cssPageTop, cssPageRight, cssPageBottom,
zoom;
metrics->GetX(&x);
metrics->GetY(&y);
metrics->GetWidth(&width);
metrics->GetHeight(&height);
metrics->GetPageLeft(&pageLeft);
metrics->GetPageTop(&pageTop);
metrics->GetPageRight(&pageRight);
metrics->GetPageBottom(&pageBottom);
metrics->GetCssPageLeft(&cssPageLeft);
metrics->GetCssPageTop(&cssPageTop);
metrics->GetCssPageRight(&cssPageRight);
metrics->GetCssPageBottom(&cssPageBottom);
metrics->GetZoom(&zoom);
jobject jobj = env->NewObject(AndroidGeckoLayerClient::jViewportClass, AndroidGeckoLayerClient::jViewportCtor,
x, y, width, height,
pageLeft, pageTop, pageRight, pageBottom,
cssPageLeft, cssPageTop, cssPageRight, cssPageBottom, zoom);
return jobj;
}
class nsAndroidDisplayport : public nsIAndroidDisplayport
{
public:
NS_DECL_ISUPPORTS
virtual nsresult GetLeft(float *aLeft) { *aLeft = mLeft; return NS_OK; }
virtual nsresult GetTop(float *aTop) { *aTop = mTop; return NS_OK; }
virtual nsresult GetRight(float *aRight) { *aRight = mRight; return NS_OK; }
virtual nsresult GetBottom(float *aBottom) { *aBottom = mBottom; return NS_OK; }
virtual nsresult GetResolution(float *aResolution) { *aResolution = mResolution; return NS_OK; }
virtual nsresult SetLeft(float aLeft) { mLeft = aLeft; return NS_OK; }
virtual nsresult SetTop(float aTop) { mTop = aTop; return NS_OK; }
virtual nsresult SetRight(float aRight) { mRight = aRight; return NS_OK; }
virtual nsresult SetBottom(float aBottom) { mBottom = aBottom; return NS_OK; }
virtual nsresult SetResolution(float aResolution) { mResolution = aResolution; return NS_OK; }
nsAndroidDisplayport(AndroidRectF aRect, float aResolution):
mLeft(aRect.Left()), mTop(aRect.Top()), mRight(aRect.Right()), mBottom(aRect.Bottom()), mResolution(aResolution) {}
private:
~nsAndroidDisplayport() {}
float mLeft, mTop, mRight, mBottom, mResolution;
};
NS_IMPL_ISUPPORTS1(nsAndroidDisplayport, nsIAndroidDisplayport)
void createDisplayPort(AutoLocalJNIFrame *jniFrame, jobject jobj, nsIAndroidDisplayport** displayPort) {
JNIEnv* env = jniFrame->GetEnv();
AndroidRectF rect(env, env->GetObjectField(jobj, AndroidGeckoLayerClient::jDisplayportPosition));
if (jniFrame->CheckForException()) return;
float resolution = env->GetFloatField(jobj, AndroidGeckoLayerClient::jDisplayportResolution);
if (jniFrame->CheckForException()) return;
*displayPort = new nsAndroidDisplayport(rect, resolution);
}
void
AndroidGeckoLayerClient::GetDisplayPort(AutoLocalJNIFrame *jniFrame, bool aPageSizeUpdate, bool aIsBrowserContentDisplayed, int32_t tabId, nsIAndroidViewport* metrics, nsIAndroidDisplayport** displayPort)
{
jobject jmetrics = ConvertToJavaViewportMetrics(jniFrame->GetEnv(), metrics);
if (jniFrame->CheckForException()) return;
if (!jmetrics)
return;
jobject jobj = jniFrame->GetEnv()->CallObjectMethod(wrapped_obj, jGetDisplayPort, aPageSizeUpdate, aIsBrowserContentDisplayed, tabId, jmetrics);
if (jniFrame->CheckForException()) return;
createDisplayPort(jniFrame, jobj, displayPort);
(*displayPort)->AddRef();
}
jobject
AndroidGeckoSurfaceView::GetSoftwareDrawBitmap(AutoLocalJNIFrame *jniFrame)
{
@ -956,6 +1065,26 @@ AndroidRect::Init(JNIEnv *jenv, jobject jobj)
}
}
void
AndroidRectF::Init(JNIEnv *jenv, jobject jobj)
{
NS_ASSERTION(wrapped_obj == nullptr, "Init called on non-null wrapped_obj!");
wrapped_obj = jobj;
if (jobj) {
mTop = jenv->GetFloatField(jobj, jTopField);
mLeft = jenv->GetFloatField(jobj, jLeftField);
mRight = jenv->GetFloatField(jobj, jRightField);
mBottom = jenv->GetFloatField(jobj, jBottomField);
} else {
mTop = 0;
mLeft = 0;
mRight = 0;
mBottom = 0;
}
}
nsJNIString::nsJNIString(jstring jstr, JNIEnv *jenv)
{
if (!jstr) {

View File

@ -25,6 +25,10 @@
#endif
#endif
class nsIAndroidDisplayport;
class nsIAndroidViewport;
namespace mozilla {
class AndroidGeckoLayerClient;
@ -144,6 +148,38 @@ protected:
static jfieldID jTopField;
};
class AndroidRectF : public WrappedJavaObject
{
public:
static void InitRectFClass(JNIEnv *jEnv);
AndroidRectF() { }
AndroidRectF(JNIEnv *jenv, jobject jobj) {
Init(jenv, jobj);
}
void Init(JNIEnv *jenv, jobject jobj);
float Bottom() { return mBottom; }
float Left() { return mLeft; }
float Right() { return mRight; }
float Top() { return mTop; }
float Width() { return mRight - mLeft; }
float Height() { return mBottom - mTop; }
protected:
float mBottom;
float mLeft;
float mRight;
float mTop;
static jclass jRectClass;
static jfieldID jBottomField;
static jfieldID jLeftField;
static jfieldID jRightField;
static jfieldID jTopField;
};
class AndroidViewTransform : public WrappedJavaObject {
public:
static void InitViewTransformClass(JNIEnv *jEnv);
@ -200,6 +236,7 @@ public:
bool CreateFrame(AutoLocalJNIFrame *jniFrame, AndroidLayerRendererFrame& aFrame);
bool ActivateProgram(AutoLocalJNIFrame *jniFrame);
bool DeactivateProgram(AutoLocalJNIFrame *jniFrame);
void GetDisplayPort(AutoLocalJNIFrame *jniFrame, bool aPageSizeUpdate, bool aIsBrowserContentDisplayed, int32_t tabId, nsIAndroidViewport* metrics, nsIAndroidDisplayport** displayPort);
protected:
static jclass jGeckoLayerClientClass;
@ -209,6 +246,14 @@ protected:
static jmethodID jCreateFrameMethod;
static jmethodID jActivateProgramMethod;
static jmethodID jDeactivateProgramMethod;
static jmethodID jGetDisplayPort;
public:
static jclass jViewportClass;
static jclass jDisplayportClass;
static jmethodID jViewportCtor;
static jfieldID jDisplayportPosition;
static jfieldID jDisplayportResolution;
};
class AndroidGeckoSurfaceView : public WrappedJavaObject

View File

@ -15,10 +15,36 @@ interface nsIBrowserTab : nsISupports {
interface nsIAndroidBrowserApp : nsISupports {
nsIBrowserTab getBrowserTab(in int32_t tabId);
};
[scriptable, uuid(59cfcb35-69b7-47b2-8155-32b193272666)]
interface nsIAndroidViewport : nsISupports {
readonly attribute float x;
readonly attribute float y;
readonly attribute float width;
readonly attribute float height;
readonly attribute float pageLeft;
readonly attribute float pageTop;
readonly attribute float pageRight;
readonly attribute float pageBottom;
readonly attribute float cssPageLeft;
readonly attribute float cssPageTop;
readonly attribute float cssPageRight;
readonly attribute float cssPageBottom;
readonly attribute float zoom;
};
[scriptable, uuid(e1bfbc07-dbae-409d-a5b5-ef57522c1f15)]
interface nsIAndroidDisplayport : nsISupports {
attribute float left;
attribute float top;
attribute float right;
attribute float bottom;
attribute float resolution;
};
[scriptable, uuid(bbb8e0d7-5cca-4ad0-88be-538ce6d04f63)]
interface nsIAndroidBridge : nsISupports
{
AString handleGeckoMessage(in AString message);
attribute nsIAndroidBrowserApp browserApp;
nsIAndroidDisplayport getDisplayPort(in boolean aPageSizeUpdate, in boolean isBrowserContentDisplayed, in int32_t tabId, in nsIAndroidViewport metrics);
};