Bug 1306083 - 2. Pass in window object for nsIAndroidBridge calls; r=snorp
authorJim Chen <nchen@mozilla.com>
Mon, 03 Oct 2016 12:26:00 -0400
changeset 316242 c8bc3190f954648126d0be55e2af3b60e94fa1ef
parent 316241 da5048d1f778638937d5d30b08d40b14ecbf68fc
child 316243 db8b6698e822cbbf072e47230c499070a24eaaaf
push id1
push usermaklebus@msu.edu
push dateWed, 05 Oct 2016 23:10:55 +0000
reviewerssnorp
bugs1306083
milestone52.0a1
Bug 1306083 - 2. Pass in window object for nsIAndroidBridge calls; r=snorp Make contentDocumentChanged and isContentDocumentDisplayed calls require the caller to pass in a window object, so that we can get the widget and GeckoLayerClient from the window object. This way these calls no longer depend on having a global layer client in AndroidBridge.
mobile/android/chrome/content/browser.js
widget/android/AndroidBridge.cpp
widget/android/AndroidBridge.h
widget/android/nsIAndroidBridge.idl
--- a/mobile/android/chrome/content/browser.js
+++ b/mobile/android/chrome/content/browser.js
@@ -1046,31 +1046,31 @@ var BrowserApp = {
 
   // This function returns false during periods where the browser displayed document is
   // different from the browser content document, so user actions and some kinds of viewport
   // updates should be ignored. This period starts when we start loading a new page or
   // switch tabs, and ends when the new browser content document has been drawn and handed
   // off to the compositor.
   isBrowserContentDocumentDisplayed: function() {
     try {
-      if (!Services.androidBridge.isContentDocumentDisplayed())
+      if (!Services.androidBridge.isContentDocumentDisplayed(window))
         return false;
     } catch (e) {
       return false;
     }
 
     let tab = this.selectedTab;
     if (!tab)
       return false;
     return tab.contentDocumentIsDisplayed;
   },
 
   contentDocumentChanged: function() {
     window.top.QueryInterface(Ci.nsIInterfaceRequestor).getInterface(Ci.nsIDOMWindowUtils).isFirstPaint = true;
-    Services.androidBridge.contentDocumentChanged();
+    Services.androidBridge.contentDocumentChanged(window);
   },
 
   get tabs() {
     return this._tabs;
   },
 
   set selectedTab(aTab) {
     if (this._selectedTab == aTab)
--- a/widget/android/AndroidBridge.cpp
+++ b/widget/android/AndroidBridge.cpp
@@ -48,16 +48,17 @@
 #include "GLContextProvider.h"
 
 #include "mozilla/TimeStamp.h"
 #include "mozilla/UniquePtr.h"
 #include "mozilla/dom/ContentChild.h"
 #include "nsIObserverService.h"
 #include "nsISupportsPrimitives.h"
 #include "MediaPrefs.h"
+#include "WidgetUtils.h"
 
 #include "FennecJNIWrappers.h"
 
 using namespace mozilla;
 using namespace mozilla::gfx;
 using namespace mozilla::jni;
 using namespace mozilla::java;
 
@@ -1135,25 +1136,26 @@ NS_IMETHODIMP nsAndroidBridge::HandleGec
         NS_LITERAL_CSTRING("nsIAndroidBridge"),
         nullptr);
 
     JS::RootedObject object(cx, &jsonVal.toObject());
     AndroidBridge::Bridge()->HandleGeckoMessage(cx, object);
     return NS_OK;
 }
 
-NS_IMETHODIMP nsAndroidBridge::ContentDocumentChanged()
+NS_IMETHODIMP nsAndroidBridge::ContentDocumentChanged(mozIDOMWindowProxy* aWindow)
 {
-    AndroidBridge::Bridge()->ContentDocumentChanged();
+    AndroidBridge::Bridge()->ContentDocumentChanged(aWindow);
     return NS_OK;
 }
 
-NS_IMETHODIMP nsAndroidBridge::IsContentDocumentDisplayed(bool *aRet)
+NS_IMETHODIMP nsAndroidBridge::IsContentDocumentDisplayed(mozIDOMWindowProxy* aWindow,
+                                                          bool *aRet)
 {
-    *aRet = AndroidBridge::Bridge()->IsContentDocumentDisplayed();
+    *aRet = AndroidBridge::Bridge()->IsContentDocumentDisplayed(aWindow);
     return NS_OK;
 }
 
 NS_IMETHODIMP
 nsAndroidBridge::Observe(nsISupports* aSubject, const char* aTopic,
                          const char16_t* aData)
 {
   if (!strcmp(aTopic, "xpcom-shutdown")) {
@@ -1306,32 +1308,47 @@ NS_IMETHODIMP nsAndroidBridge::SetBrowse
     return NS_OK;
 }
 
 extern "C"
 __attribute__ ((visibility("default")))
 jobject JNICALL
 Java_org_mozilla_gecko_GeckoAppShell_allocateDirectBuffer(JNIEnv *env, jclass, jlong size);
 
+static jni::DependentRef<java::GeckoLayerClient>
+GetJavaLayerClient(mozIDOMWindowProxy* aWindow)
+{
+    MOZ_ASSERT(aWindow);
+
+    nsCOMPtr<nsPIDOMWindowOuter> domWindow = nsPIDOMWindowOuter::From(aWindow);
+    nsCOMPtr<nsIWidget> widget =
+            widget::WidgetUtils::DOMWindowToWidget(domWindow);
+    MOZ_ASSERT(widget);
+
+    return static_cast<nsWindow*>(widget.get())->GetLayerClient();
+}
+
 void
-AndroidBridge::ContentDocumentChanged()
+AndroidBridge::ContentDocumentChanged(mozIDOMWindowProxy* aWindow)
 {
-    if (!mLayerClient) {
+    auto layerClient = GetJavaLayerClient(aWindow);
+    if (!layerClient) {
         return;
     }
-    mLayerClient->ContentDocumentChanged();
+    layerClient->ContentDocumentChanged();
 }
 
 bool
-AndroidBridge::IsContentDocumentDisplayed()
+AndroidBridge::IsContentDocumentDisplayed(mozIDOMWindowProxy* aWindow)
 {
-    if (!mLayerClient)
+    auto layerClient = GetJavaLayerClient(aWindow);
+    if (!layerClient) {
         return false;
-
-    return mLayerClient->IsContentDocumentDisplayed();
+    }
+    return layerClient->IsContentDocumentDisplayed();
 }
 
 class AndroidBridge::DelayedTask
 {
     using TimeStamp = mozilla::TimeStamp;
     using TimeDuration = mozilla::TimeDuration;
 
 public:
--- a/widget/android/AndroidBridge.h
+++ b/widget/android/AndroidBridge.h
@@ -139,18 +139,18 @@ public:
 
     static void ConstructBridge();
     static void DeconstructBridge();
 
     static AndroidBridge *Bridge() {
         return sBridge;
     }
 
-    void ContentDocumentChanged();
-    bool IsContentDocumentDisplayed();
+    void ContentDocumentChanged(mozIDOMWindowProxy* aDOMWindow);
+    bool IsContentDocumentDisplayed(mozIDOMWindowProxy* aDOMWindow);
 
     void SetLayerClient(java::GeckoLayerClient::Param jobj);
     const java::GeckoLayerClient::Ref& GetLayerClient() { return mLayerClient; }
 
     bool GetHandlersForURL(const nsAString& aURL,
                            nsIMutableArray* handlersArray = nullptr,
                            nsIHandlerApp **aDefaultApp = nullptr,
                            const nsAString& aAction = EmptyString());
--- a/widget/android/nsIAndroidBridge.idl
+++ b/widget/android/nsIAndroidBridge.idl
@@ -32,11 +32,11 @@ interface nsIAndroidBrowserApp : nsISupp
   nsIUITelemetryObserver getUITelemetryObserver();
 };
 
 [scriptable, uuid(1beb70d3-70f3-4742-98cc-a3d301b26c0c)]
 interface nsIAndroidBridge : nsISupports
 {
   [implicit_jscontext] void handleGeckoMessage(in jsval message);
   attribute nsIAndroidBrowserApp browserApp;
-  void contentDocumentChanged();
-  boolean isContentDocumentDisplayed();
+  void contentDocumentChanged(in mozIDOMWindowProxy window);
+  boolean isContentDocumentDisplayed(in mozIDOMWindowProxy window);
 };