Bug 516728 - Remote link-visited information. r=sdwilsh, sr=bz
authorDoug Turner <dougt@dougt.org>
Fri, 02 Jul 2010 08:50:41 -0700
changeset 48297 9ebd1145c98ae09287bfb80f7b07a24c37d3229b
parent 48296 f9214514d547d172141f4c5ee4ae975b83b70488
child 48298 da160d0117e718de1c2e9b4e580e7f461c8164ff
push id14671
push userdougt@mozilla.com
push dateWed, 28 Jul 2010 16:52:44 +0000
treeherdermozilla-central@da160d0117e7 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerssdwilsh, bz
bugs516728
milestone2.0b3pre
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 516728 - Remote link-visited information. r=sdwilsh, sr=bz
docshell/base/IHistory.h
dom/ipc/ContentChild.cpp
dom/ipc/ContentChild.h
dom/ipc/ContentParent.cpp
dom/ipc/ContentParent.h
dom/ipc/Makefile.in
dom/ipc/PContent.ipdl
toolkit/components/places/src/History.cpp
toolkit/components/places/src/Makefile.in
--- a/docshell/base/IHistory.h
+++ b/docshell/base/IHistory.h
@@ -47,17 +47,17 @@ class nsString;
 
 namespace mozilla {
 
     namespace dom {
         class Link;
     }
 
 #define IHISTORY_IID \
-  {0x6f736049, 0x6370, 0x4376, {0xb7, 0x17, 0xfa, 0xfc, 0x0b, 0x4f, 0xd0, 0xf1}}
+  {0x6f733924, 0x6321, 0x4384, {0x01, 0xee, 0x8e, 0x7d, 0xfb, 0xde, 0xe7, 0xa8}}
 
 class IHistory : public nsISupports
 {
 public:
     NS_DECLARE_STATIC_IID_ACCESSOR(IHISTORY_IID)
 
     /**
      * Registers the Link for notifications about the visited-ness of aURI.
@@ -66,17 +66,17 @@ public:
      * SetLinkState called on themselves.  This function is guaranteed to run to
      * completion before aLink is notified.  After the node is notified, it will
      * be unregistered.
      *
      * @note SetLinkState must not call RegisterVisitedCallback or
      *       UnregisterVisitedCallback.
      *
      * @pre aURI must not be null.
-     * @pre aLink must not be null.
+     * @pre aLink may be null only in the MOZ_IPC parent process.
      *
      * @param aURI
      *        The URI to check.
      * @param aLink
      *        The link to update whenever the history status changes.  The
      *        implementation will only hold onto a raw pointer, so if this
      *        object should be destroyed, be sure to call
      *        UnregisterVistedCallback first.
--- a/dom/ipc/ContentChild.cpp
+++ b/dom/ipc/ContentChild.cpp
@@ -49,24 +49,29 @@
 #include "nsTObserverArray.h"
 #include "nsIObserver.h"
 #include "nsIPrefService.h"
 #include "nsIPrefBranch.h"
 #include "nsServiceManagerUtils.h"
 #include "nsXULAppAPI.h"
 #include "nsWeakReference.h"
 
+#include "History.h"
+#include "nsDocShellCID.h"
+#include "nsNetUtil.h"
+
 #include "base/message_loop.h"
 #include "base/task.h"
 
 #include "nsChromeRegistryContent.h"
 #include "mozilla/chrome/RegistryMessageUtils.h"
 
 using namespace mozilla::ipc;
 using namespace mozilla::net;
+using namespace mozilla::places;
 
 namespace mozilla {
 namespace dom {
 
 class PrefObserver
 {
 public:
     /**
@@ -338,10 +343,18 @@ ContentChild::RecvNotifyRemotePrefObserv
             mPrefObservers.RemoveElementAt(i);
             continue;
         }
         ++i;
     }
     return true;
 }
 
+bool
+ContentChild::RecvNotifyVisited(const IPC::URI& aURI)
+{
+    nsCOMPtr<nsIURI> newURI = aURI;
+    History::GetService()->NotifyVisited(newURI);
+    return true;
+}
+
 } // namespace dom
 } // namespace mozilla
--- a/dom/ipc/ContentChild.h
+++ b/dom/ipc/ContentChild.h
@@ -83,16 +83,18 @@ public:
     virtual bool DeallocPNecko(PNeckoChild*);
 
     virtual bool RecvRegisterChrome(const nsTArray<ChromePackage>& packages,
                                     const nsTArray<ResourceMapping>& resources,
                                     const nsTArray<OverrideMapping>& overrides);
 
     virtual bool RecvSetOffline(const PRBool& offline);
 
+    virtual bool RecvNotifyVisited(const IPC::URI& aURI);
+
     /**
      * Notify |aObserver| of changes to |aPrefRoot|.|aDomain|.  If
      * |aHoldWeak|, only a weak reference to |aObserver| is held.
      */
     nsresult AddRemotePrefObserver(const nsCString& aDomain, 
                                    const nsCString& aPrefRoot, 
                                    nsIObserver* aObserver, PRBool aHoldWeak);
     nsresult RemoveRemotePrefObserver(const nsCString& aDomain, 
--- a/dom/ipc/ContentParent.cpp
+++ b/dom/ipc/ContentParent.cpp
@@ -35,31 +35,33 @@
  * 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 ***** */
 
 #include "ContentParent.h"
 
 #include "TabParent.h"
+#include "History.h"
 #include "mozilla/ipc/TestShellParent.h"
 #include "mozilla/net/NeckoParent.h"
 #include "nsIPrefBranch.h"
 #include "nsIPrefBranch2.h"
 #include "nsIPrefLocalizedString.h"
 #include "nsIObserverService.h"
 
 #include "nsAutoPtr.h"
 #include "nsCOMPtr.h"
 #include "nsServiceManagerUtils.h"
 #include "nsThreadUtils.h"
 #include "nsChromeRegistryChrome.h"
 
 using namespace mozilla::ipc;
 using namespace mozilla::net;
+using namespace mozilla::places;
 using mozilla::MonitorAutoEnter;
 
 namespace mozilla {
 namespace dom {
 
 #define NS_IPC_IOSERVICE_SET_OFFLINE_TOPIC "ipc:network:set-offline"
 
 ContentParent* ContentParent::gSingleton;
@@ -425,16 +427,25 @@ ContentParent::RequestRunToCompletion()
         printf("Running to completion...\n");
 #endif
         mRunToCompletionDepth = 1;
         mShouldCallUnblockChild = true;
     }
     return !!mRunToCompletionDepth;
 }
 
+bool
+ContentParent::RecvStartVisitedQuery(const IPC::URI& aURI)
+{
+    nsCOMPtr<nsIURI> newURI = aURI;
+    IHistory *history = nsContentUtils::GetHistory(); 
+    history->RegisterVisitedCallback(newURI, nsnull);
+    return true;
+}
+
 /* void onDispatchedEvent (in nsIThreadInternal thread); */
 NS_IMETHODIMP
 ContentParent::OnDispatchedEvent(nsIThreadInternal *thread)
 {
     if (mOldObserver)
         return mOldObserver->OnDispatchedEvent(thread);
 
     return NS_OK;
--- a/dom/ipc/ContentParent.h
+++ b/dom/ipc/ContentParent.h
@@ -140,16 +140,18 @@ private:
     virtual bool RecvTestPermission(const IPC::URI&  aUri,
                                     const nsCString& aType,
                                     const PRBool&    aExact,
                                     PRUint32*        retValue);
 
     void EnsurePrefService();
     void EnsurePermissionService();
 
+    virtual bool RecvStartVisitedQuery(const IPC::URI& uri);
+
     mozilla::Monitor mMonitor;
 
     GeckoChildProcessHost* mSubprocess;
 
     int mRunToCompletionDepth;
     bool mShouldCallUnblockChild;
     nsCOMPtr<nsIThreadObserver> mOldObserver;
 
--- a/dom/ipc/Makefile.in
+++ b/dom/ipc/Makefile.in
@@ -74,15 +74,16 @@ CPPSRCS = \
 
 include $(topsrcdir)/config/config.mk
 include $(topsrcdir)/ipc/chromium/chromium-config.mk
 include $(topsrcdir)/config/rules.mk
 
 LOCAL_INCLUDES += \
 		-I$(srcdir)/../../content/base/src \
 		-I$(srcdir)/../../content/events/src \
+		-I$(srcdir)/../../toolkit/components/places/src \
 		-I$(srcdir)/../src/geolocation \
 		-I$(topsrcdir)/chrome/src \
 		$(NULL)
 
 CXXFLAGS += $(TK_CFLAGS)
 
 DEFINES += -DBIN_SUFFIX='"$(BIN_SUFFIX)"'
--- a/dom/ipc/PContent.ipdl
+++ b/dom/ipc/PContent.ipdl
@@ -63,23 +63,27 @@ child:
 
     PTestShell();
 
     RegisterChrome(ChromePackage[] packages, ResourceMapping[] resources,
                    OverrideMapping[] overrides);
 
     async SetOffline(PRBool offline);
 
+    async NotifyVisited(URI uri);
+
     NotifyRemotePrefObserver(nsCString aDomain);
 
 parent:
     PNecko();
 
     // Services remoting
 
+    async StartVisitedQuery(URI uri);
+
     // PrefService messages
     sync GetPrefType(nsCString prefName) returns (PRInt32 retValue, nsresult rv);
     sync GetBoolPref(nsCString prefName) returns (PRBool retValue, nsresult rv);
     sync GetIntPref(nsCString prefName)  returns (PRInt32 retValue, nsresult rv);
     sync GetCharPref(nsCString prefName) returns (nsCString retValue, nsresult rv);
     sync GetPrefLocalizedString(nsCString prefName) returns (nsString retValue, nsresult rv);
     sync PrefHasUserValue(nsCString prefName) returns (PRBool retValue, nsresult rv);
     sync PrefIsLocked(nsCString prefName) returns (PRBool retValue, nsresult rv);
--- a/toolkit/components/places/src/History.cpp
+++ b/toolkit/components/places/src/History.cpp
@@ -32,16 +32,22 @@
  * 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/ContentChild.h"
+#include "mozilla/dom/ContentParent.h"
+#include "nsXULAppAPI.h"
+#endif
+
 #include "History.h"
 #include "nsNavHistory.h"
 #include "nsNavBookmarks.h"
 #include "Helpers.h"
 
 #include "mozilla/storage.h"
 #include "mozilla/dom/Link.h"
 #include "nsDocShellCID.h"
@@ -150,16 +156,28 @@ class VisitedQuery : public mozIStorageS
 {
 public:
   NS_DECL_ISUPPORTS
 
   static nsresult Start(nsIURI* aURI)
   {
     NS_PRECONDITION(aURI, "Null URI");
 
+#ifdef MOZ_IPC
+  // If we are a content process, always remote the request to the
+  // parent process.
+  if (XRE_GetProcessType() == GeckoProcessType_Content) {
+    mozilla::dom::ContentChild * cpc = 
+      mozilla::dom::ContentChild::GetSingleton();
+    NS_ASSERTION(cpc, "Content Protocol is NULL!");
+    (void)cpc->SendStartVisitedQuery(IPC::URI(aURI));
+    return NS_OK;
+  }
+#endif
+
     nsNavHistory* navHist = nsNavHistory::GetHistoryService();
     NS_ENSURE_TRUE(navHist, NS_ERROR_FAILURE);
     mozIStorageStatement* stmt = navHist->GetStatementById(DB_IS_PAGE_VISITED);
     NS_ENSURE_STATE(stmt);
 
     // Bind by index for performance.
     nsresult rv = URIBinder::Bind(stmt, 0, aURI);
     NS_ENSURE_SUCCESS(rv, rv);
@@ -951,16 +969,25 @@ History::CurrentTaskFinished()
   StartNextTask();
 }
 
 void
 History::NotifyVisited(nsIURI* aURI)
 {
   NS_ASSERTION(aURI, "Ruh-roh!  A NULL URI was passed to us!");
 
+#ifdef MOZ_IPC
+  if (XRE_GetProcessType() == GeckoProcessType_Default) {
+    mozilla::dom::ContentParent* cpp = 
+      mozilla::dom::ContentParent::GetSingleton(PR_FALSE);
+    if (cpp)
+      (void)cpp->SendNotifyVisited(IPC::URI(aURI));
+  }
+#endif
+
   // If the hash table has not been initialized, then we have nothing to notify
   // about.
   if (!mObservers.IsInitialized()) {
     return;
   }
 
   // Additionally, if we have no observers for this URI, we have nothing to
   // notify about.
@@ -1130,17 +1157,24 @@ History::VisitURI(nsIURI* aURI,
   return NS_OK;
 }
 
 NS_IMETHODIMP
 History::RegisterVisitedCallback(nsIURI* aURI,
                                  Link* aLink)
 {
   NS_ASSERTION(aURI, "Must pass a non-null URI!");
-  NS_ASSERTION(aLink, "Must pass a non-null Link object!");
+#ifdef MOZ_IPC
+  if (XRE_GetProcessType() == GeckoProcessType_Content) {
+    NS_PRECONDITION(aLink, "Must pass a non-null URI!");
+  }
+#else
+  NS_PRECONDITION(aLink, "Must pass a non-null URI!");
+#endif
+
 
   // First, ensure that our hash table is setup.
   if (!mObservers.IsInitialized()) {
     NS_ENSURE_TRUE(mObservers.Init(), NS_ERROR_OUT_OF_MEMORY);
   }
 
   // Obtain our array of observers for this URI.
 #ifdef DEBUG
@@ -1153,17 +1187,17 @@ 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);
-    if (NS_FAILED(rv)) {
+    if (NS_FAILED(rv) || !aLink) {
       // 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.
   // This will not catch a case where it is registered for two different URIs.
--- 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 \