imported patch bug_516728_is_visited
authorDoug Turner <dougt@dougt.org>
Fri, 19 Mar 2010 00:05:29 -0700
changeset 46747 b40fa2e11f973fe441d52bc72ee8d9b9d34bfb55
parent 46746 e3a36a0d37aa0da05db3b98207cd8d28c6542b7a
child 46748 cfbe4fa1679e529788f372c80d35b86d55ade173
push id14210
push userdougt@mozilla.com
push dateThu, 01 Jul 2010 06:28:42 +0000
treeherdermozilla-central@3aff97777291 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
milestone1.9.3a4pre
imported patch bug_516728_is_visited
dom/ipc/ContentProcessChild.cpp
dom/ipc/ContentProcessChild.h
dom/ipc/ContentProcessParent.cpp
dom/ipc/ContentProcessParent.h
dom/ipc/Makefile.in
dom/ipc/PContentProcess.ipdl
toolkit/components/places/src/History.cpp
toolkit/components/places/src/History.h
toolkit/components/places/src/Makefile.in
--- a/dom/ipc/ContentProcessChild.cpp
+++ b/dom/ipc/ContentProcessChild.cpp
@@ -36,26 +36,30 @@
  *
  * ***** END LICENSE BLOCK ***** */
 
 #include "ContentProcessChild.h"
 #include "TabChild.h"
 
 #include "mozilla/ipc/TestShellChild.h"
 #include "mozilla/net/NeckoChild.h"
+#include "History.h"
 
 #include "nsXULAppAPI.h"
 
+#include "nsDocShellCID.h"
+#include "nsNetUtil.h"
 #include "base/message_loop.h"
 #include "base/task.h"
 
 #include "nsChromeRegistry.h"
 
 using namespace mozilla::ipc;
 using namespace mozilla::net;
+using namespace mozilla::places;
 
 namespace mozilla {
 namespace dom {
 
 ContentProcessChild* ContentProcessChild::sSingleton;
 
 ContentProcessChild::ContentProcessChild()
     : mQuit(PR_FALSE)
@@ -154,10 +158,29 @@ ContentProcessChild::ActorDestroy(ActorD
         NS_WARNING("shutting down because of crash!");
 
     mQuit = PR_TRUE;
     Quit();
 
     XRE_ShutdownChildProcess();
 }
 
+bool
+ContentProcessChild::RecvNotifyVisited(const nsCString& aURISpec, 
+                                       const bool& mIsVisited)
+{
+    nsresult rv;
+
+    // reconstruct our IPDL-passed nsIURI
+    nsCOMPtr<nsIURI> newURI;
+    rv = NS_NewURI(getter_AddRefs(newURI), aURISpec);
+    // Our failure mode is to consider the link unvisited.
+    if (NS_SUCCEEDED(rv)) {
+        History *hs = History::GetSingleton();
+        if (hs) {
+            hs->NotifyVisited(newURI, mIsVisited);
+        }
+    }
+    return true;
+}
+
 } // namespace dom
 } // namespace mozilla
--- a/dom/ipc/ContentProcessChild.h
+++ b/dom/ipc/ContentProcessChild.h
@@ -72,16 +72,19 @@ public:
     virtual PNeckoChild* AllocPNecko();
     virtual bool DeallocPNecko(PNeckoChild*);
 
     virtual bool RecvDummy(Shmem& foo) { return true; }
 
     virtual bool RecvregisterChrome(const nsTArray<ChromePackage>& packages,
                                     const nsTArray<ChromeResource>& resources);
 
+    virtual bool
+    RecvNotifyVisited(const nsCString& aURISpec, const bool& mIsVisited);
+
 private:
     NS_OVERRIDE
     virtual void ActorDestroy(ActorDestroyReason why);
 
     void Quit();
 
     static ContentProcessChild* sSingleton;
 
--- a/dom/ipc/ContentProcessParent.cpp
+++ b/dom/ipc/ContentProcessParent.cpp
@@ -36,23 +36,26 @@
  *
  * ***** END LICENSE BLOCK ***** */
 
 #include "ContentProcessParent.h"
 
 #include "TabParent.h"
 #include "mozilla/ipc/TestShellParent.h"
 #include "mozilla/net/NeckoParent.h"
+#include "mozilla/IHistory.h"
 
 #include "nsIObserverService.h"
 
 #include "nsAutoPtr.h"
 #include "nsCOMPtr.h"
+#include "nsDocShellCID.h"
 #include "nsServiceManagerUtils.h"
 #include "nsThreadUtils.h"
+#include "nsNetUtil.h"
 #include "nsChromeRegistry.h"
 
 using namespace mozilla::ipc;
 using namespace mozilla::net;
 using mozilla::MonitorAutoEnter;
 
 namespace mozilla {
 namespace dom {
@@ -228,16 +231,33 @@ ContentProcessParent::RequestRunToComple
         printf("Running to completion...\n");
 #endif
         mRunToCompletionDepth = 1;
     }
 
     return !!mRunToCompletionDepth;
 }
 
+bool
+ContentProcessParent::RecvStartVisitedQuery(const nsCString& aURISpec, nsresult* rv)
+{
+    // reconstruct our IPDL-passed nsIURI
+    nsCOMPtr<nsIURI> newURI;
+    *rv = NS_NewURI(getter_AddRefs(newURI), aURISpec);
+    if (NS_SUCCEEDED(*rv)) {
+        nsCOMPtr<IHistory> history = do_GetService(NS_IHISTORY_CONTRACTID);
+        if (history) {
+            *rv = history->RegisterVisitedCallback(newURI, nsnull);
+        }
+    } else {
+        *rv = NS_ERROR_UNEXPECTED; 
+    }  
+    return true;
+}
+
 /* void onDispatchedEvent (in nsIThreadInternal thread); */
 NS_IMETHODIMP
 ContentProcessParent::OnDispatchedEvent(nsIThreadInternal *thread)
 {
     if (mOldObserver)
         return mOldObserver->OnDispatchedEvent(thread);
 
     return NS_OK;
--- a/dom/ipc/ContentProcessParent.h
+++ b/dom/ipc/ContentProcessParent.h
@@ -105,16 +105,18 @@ private:
     virtual bool DeallocPIFrameEmbedding(PIFrameEmbeddingParent* frame);
 
     virtual PTestShellParent* AllocPTestShell();
     virtual bool DeallocPTestShell(PTestShellParent* shell);
 
     virtual PNeckoParent* AllocPNecko();
     virtual bool DeallocPNecko(PNeckoParent* necko);
 
+    virtual bool RecvStartVisitedQuery(const nsCString& aURISpec, nsresult* rv);
+
     mozilla::Monitor mMonitor;
 
     GeckoChildProcessHost* mSubprocess;
 
     int mRunToCompletionDepth;
     nsCOMPtr<nsIThreadObserver> mOldObserver;
 
     bool mIsAlive;
--- a/dom/ipc/Makefile.in
+++ b/dom/ipc/Makefile.in
@@ -71,14 +71,15 @@ CPPSRCS = \
   TabMessageUtils.cpp \
   $(NULL)
 
 include $(topsrcdir)/config/config.mk
 include $(topsrcdir)/ipc/chromium/chromium-config.mk
 include $(topsrcdir)/config/rules.mk
 
 LOCAL_INCLUDES += \
+		-I$(srcdir)/../../toolkit/components/places/src \
 		-I$(srcdir)/../../content/base/src \
 		-I$(srcdir)/../../content/events/src \
 		-I$(topsrcdir)/chrome/src \
 		$(NULL)
 
 DEFINES += -DBIN_SUFFIX='"$(BIN_SUFFIX)"'
--- a/dom/ipc/PContentProcess.ipdl
+++ b/dom/ipc/PContentProcess.ipdl
@@ -61,15 +61,17 @@ child:
 
     PTestShell();
 
     registerChrome(ChromePackage[] packages, ChromeResource[] resources);
 
     // A dummy message to make sure PContentProcess contains methods to create
     // Shmem segments.
     async Dummy(Shmem foo);
+    async NotifyVisited(nsCString aURISpec, bool mIsVisited);
 
 parent:
     PNecko();
+    sync StartVisitedQuery(nsCString aURISpec) returns (nsresult rv);
 };
 
 }
 }
--- a/toolkit/components/places/src/History.cpp
+++ b/toolkit/components/places/src/History.cpp
@@ -32,16 +32,21 @@
  * use your version of this file under the terms of the MPL, indicate your
  * decision by deleting the provisions above and replace them with the notice
  * and other provisions required by the GPL or the LGPL. If you do not delete
  * the provisions above, a recipient may use your version of this file under
  * the terms of any one of the MPL, the GPL or the LGPL.
  *
  * ***** END LICENSE BLOCK ***** */
 
+#ifdef MOZ_IPC
+#include "mozilla/dom/ContentProcessChild.h"
+#include "mozilla/dom/ContentProcessParent.h"
+#endif
+
 #include "History.h"
 #include "nsNavHistory.h"
 
 #include "mozilla/storage.h"
 #include "mozilla/dom/Link.h"
 #include "nsDocShellCID.h"
 #include "nsIEventStateManager.h"
 
@@ -104,37 +109,17 @@ public:
   {
     // mIsVisited is already set to false, and that's the assumption we will
     // make if an error occurred.
     return NS_OK;
   }
 
   NS_IMETHOD HandleCompletion(PRUint16 aReason)
   {
-    if (mIsVisited) {
-      History::GetService()->NotifyVisited(mURI);
-    }
-
-    // Notify any observers about that we have resolved the visited state of
-    // this URI.
-    nsCOMPtr<nsIObserverService> observerService =
-      do_GetService(NS_OBSERVERSERVICE_CONTRACTID);
-    if (observerService) {
-      nsAutoString status;
-      if (mIsVisited) {
-        status.AssignLiteral(URI_VISITED);
-      }
-      else {
-        status.AssignLiteral(URI_NOT_VISITED);
-      }
-      (void)observerService->NotifyObservers(mURI,
-                                             URI_VISITED_RESOLUTION_TOPIC,
-                                             status.get());
-    }
-
+    History::GetService()->NotifyVisited(mURI, mIsVisited);
     return NS_OK;
   }
 private:
   VisitedQuery(nsIURI* aURI)
   : mURI(aURI)
   , mIsVisited(false)
   {
   }
@@ -167,45 +152,77 @@ History::~History()
   if (mObservers.IsInitialized()) {
     NS_ASSERTION(mObservers.Count() == 0,
                  "Not all Links were removed before we disappear!");
   }
 #endif
 }
 
 void
-History::NotifyVisited(nsIURI* aURI)
+History::NotifyVisited(nsIURI* aURI, bool aIsVisited)
 {
   NS_ASSERTION(aURI, "Ruh-roh!  A NULL URI was passed to us!");
 
-  // If the hash table has not been initialized, then we have nothing to notify
-  // about.
-  if (!mObservers.IsInitialized()) {
-    return;
+#ifdef MOZ_IPC
+  if (XRE_GetProcessType() == GeckoProcessType_Default) {
+    mozilla::dom::ContentProcessParent * cpp = 
+        mozilla::dom::ContentProcessParent::GetSingleton();
+    NS_ASSERTION(cpp, "Content Protocol is NULL!");
+
+    nsCString aURISpec;
+    aURI->GetSpec(aURISpec);
+    cpp->SendNotifyVisited(aURISpec, aIsVisited);
   }
+#endif
 
-  // Additionally, if we have no observers for this URI, we have nothing to
-  // notify about.
-  KeyClass* key = mObservers.GetEntry(aURI);
-  if (!key) {
-    return;
-  }
+  if (aIsVisited) {
+    // If the hash table has not been initialized, then we have nothing to notify
+    // about.
+    if (!mObservers.IsInitialized()) {
+      return;
+    }
 
-  // Walk through the array, and update each Link node.
-  const ObserverArray& observers = key->array;
-  ObserverArray::index_type len = observers.Length();
-  for (ObserverArray::index_type i = 0; i < len; i++) {
-    Link* link = observers[i];
-    link->SetLinkState(eLinkState_Visited);
-    NS_ASSERTION(len == observers.Length(),
-                 "Calling SetLinkState added or removed an observer!");
-  }
+    // Additionally, if we have no observers for this URI, we have nothing to
+    // notify about.
+    KeyClass* key = mObservers.GetEntry(aURI);
+    if (!key) {
+      return;
+    }
+
+    // Walk through the array, and update each Link node.
+    const ObserverArray& observers = key->array;
+    ObserverArray::index_type len = observers.Length();
+    for (ObserverArray::index_type i = 0; i < len; i++) {
+      Link* link = observers[i];
+      link->SetLinkState(eLinkState_Visited);
+      NS_ASSERTION(len == observers.Length(),
+                   "Calling SetLinkState added or removed an observer!");
+    }
 
   // All the registered nodes can now be removed for this URI.
   mObservers.RemoveEntry(aURI);
+  }
+
+  // Notify any observers about that we have resolved the visited state of
+  // this URI.
+  nsCOMPtr<nsIObserverService> observerService =
+    do_GetService(NS_OBSERVERSERVICE_CONTRACTID);
+  if (observerService) {
+    nsAutoString status;
+    if (aIsVisited) {
+      status.AssignLiteral(URI_VISITED);
+    }
+    else {
+      status.AssignLiteral(URI_NOT_VISITED);
+    }
+    (void)observerService->NotifyObservers(aURI,
+      URI_VISITED_RESOLUTION_TOPIC,
+      status.get());
+  }
+
 }
 
 /* static */
 History*
 History::GetService()
 {
   if (gService) {
     return gService;
@@ -233,16 +250,25 @@ History::GetSingleton()
 
 ////////////////////////////////////////////////////////////////////////////////
 //// IHistory
 
 NS_IMETHODIMP
 History::RegisterVisitedCallback(nsIURI* aURI,
                                  Link* aLink)
 {
+  nsresult   rv;
+
+#ifdef MOZ_IPC
+  if (XRE_GetProcessType() == GeckoProcessType_Default) {
+      rv = VisitedQuery::Start(aURI);
+      return rv;
+  }
+#endif
+
   NS_ASSERTION(aURI, "Must pass a non-null URI!");
   NS_ASSERTION(aLink, "Must pass a non-null Link object!");
 
   // First, ensure that our hash table is setup.
   if (!mObservers.IsInitialized()) {
     NS_ENSURE_TRUE(mObservers.Init(), NS_ERROR_OUT_OF_MEMORY);
   }
 
@@ -256,17 +282,29 @@ History::RegisterVisitedCallback(nsIURI*
 
   if (observers.IsEmpty()) {
     NS_ASSERTION(!keyAlreadyExists,
                  "An empty key was kept around in our hashtable!");
 
     // We are the first Link node to ask about this URI, or there are no pending
     // Links wanting to know about this URI.  Therefore, we should query the
     // database now.
-    nsresult rv = VisitedQuery::Start(aURI);
+#ifdef MOZ_IPC
+  if (XRE_GetProcessType() == GeckoProcessType_Content) {
+    mozilla::dom::ContentProcessChild * cpc = 
+        mozilla::dom::ContentProcessChild::GetSingleton();
+    NS_ASSERTION(cpc, "Content Protocol is NULL!");
+
+    nsCString aURISpec;
+    aURI->GetSpec(aURISpec);
+    cpc->SendStartVisitedQuery(aURISpec, &rv);
+  }
+#else
+    rv = VisitedQuery::Start(aURI);
+#endif
     if (NS_FAILED(rv)) {
       // Remove our array from the hashtable so we don't keep it around.
       mObservers.RemoveEntry(aURI);
       return rv;
     }
   }
 
   // Sanity check that Links are not registered more than once for a given URI.
--- a/toolkit/components/places/src/History.h
+++ b/toolkit/components/places/src/History.h
@@ -62,17 +62,17 @@ public:
   History();
 
   /**
    * Notifies about the visited status of a given URI.
    *
    * @param aURI
    *        The URI to notify about.
    */
-  void NotifyVisited(nsIURI *aURI);
+  void NotifyVisited(nsIURI *aURI, bool mIsVisited = true);
 
   /**
    * Obtains a pointer to this service.
    */
   static History *GetService();
 
   /**
    * Obtains a pointer that has had AddRef called on it.  Used by the service
--- a/toolkit/components/places/src/Makefile.in
+++ b/toolkit/components/places/src/Makefile.in
@@ -45,16 +45,21 @@ include $(DEPTH)/config/autoconf.mk
 
 MODULE = places
 LIBRARY_NAME  = places
 LIBXUL_LIBRARY = 1
 EXPORT_LIBRARY = 1
 MODULE_NAME = nsPlacesModule
 IS_COMPONENT = 1
 
+EXPORTS_NAMESPACES = mozilla/places
+
+EXPORTS_mozilla/places = \
+  History.h \
+  $(NULL)
 
 CPPSRCS = \
           nsAnnoProtocolHandler.cpp \
           nsAnnotationService.cpp \
           nsFaviconService.cpp \
           nsNavHistory.cpp \
           nsNavHistoryQuery.cpp \
           nsNavHistoryResult.cpp \
@@ -88,9 +93,11 @@ endif
 
 EXTRA_JS_MODULES = \
   utils.js \
   PlacesDBUtils.jsm \
   $(NULL)
 
 EXTRA_PP_JS_MODULES = utils.js
 
-include $(topsrcdir)/config/rules.mk
+include $(topsrcdir)/config/config.mk
+include $(topsrcdir)/ipc/chromium/chromium-config.mk
+include $(topsrcdir)/config/rules.mk
\ No newline at end of file