Bug 949913 - Don't store page refreshes as history visits. r=blassey, a=lsblakk
authorMark Finkle <mfinkle@mozilla.com>
Mon, 16 Dec 2013 16:00:08 -0500
changeset 174558 d86ef4be9fc52ec97b73ea720ffb1982b20b350b
parent 174557 8cc47d24d9f9a947db0fcc2250056b1161ef3663
child 174559 4ecd4f2ba149231b3cb31e7d92b9da803a1cf2bd
push id3224
push userlsblakk@mozilla.com
push dateTue, 04 Feb 2014 01:06:49 +0000
treeherdermozilla-beta@60c04d0987f1 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersblassey, lsblakk
bugs949913
milestone28.0a2
Bug 949913 - Don't store page refreshes as history visits. r=blassey, a=lsblakk
mobile/android/components/build/nsAndroidHistory.cpp
mobile/android/components/build/nsAndroidHistory.h
--- a/mobile/android/components/build/nsAndroidHistory.cpp
+++ b/mobile/android/components/build/nsAndroidHistory.cpp
@@ -2,16 +2,20 @@
  * 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 "nsThreadUtils.h"
 #include "nsAndroidHistory.h"
 #include "AndroidBridge.h"
 #include "Link.h"
 #include "nsIURI.h"
+#include "mozilla/Services.h"
+#include "nsIObserverService.h"
+
+#define NS_LINK_VISITED_EVENT_TOPIC "link-visited"
 
 using namespace mozilla;
 using mozilla::dom::Link;
 
 NS_IMPL_ISUPPORTS2(nsAndroidHistory, IHistory, nsIRunnable)
 
 nsAndroidHistory* nsAndroidHistory::sHistory = nullptr;
 
@@ -73,44 +77,87 @@ nsAndroidHistory::UnregisterVisitedCallb
   list->RemoveElement(aContent);
   if (list->IsEmpty()) {
     mListeners.Remove(uriString);
     delete list;
   }
   return NS_OK;
 }
 
+void
+nsAndroidHistory::AppendToRecentlyVisitedURIs(nsIURI* aURI) {
+  if (mRecentlyVisitedURIs.Length() < RECENTLY_VISITED_URI_SIZE) {
+    // Append a new element while the array is not full.
+    mRecentlyVisitedURIs.AppendElement(aURI);
+  } else {
+    // Otherwise, replace the oldest member.
+    mRecentlyVisitedURIsNextIndex %= RECENTLY_VISITED_URI_SIZE;
+    mRecentlyVisitedURIs.ElementAt(mRecentlyVisitedURIsNextIndex) = aURI;
+    mRecentlyVisitedURIsNextIndex++;
+  }
+}
+
+inline bool
+nsAndroidHistory::IsRecentlyVisitedURI(nsIURI* aURI) {
+  bool equals = false;
+  RecentlyVisitedArray::index_type i;
+  for (i = 0; i < mRecentlyVisitedURIs.Length() && !equals; ++i) {
+    aURI->Equals(mRecentlyVisitedURIs.ElementAt(i), &equals);
+  }
+  return equals;
+}
+
 NS_IMETHODIMP
 nsAndroidHistory::VisitURI(nsIURI *aURI, nsIURI *aLastVisitedURI, uint32_t aFlags)
 {
   if (!aURI)
     return NS_OK;
 
   // Silently return if URI is something we shouldn't add to DB.
   bool canAdd;
   nsresult rv = CanAddURI(aURI, &canAdd);
   NS_ENSURE_SUCCESS(rv, rv);
   if (!canAdd) {
     return NS_OK;
   }
 
+  if (aLastVisitedURI) {
+    bool same;
+    rv = aURI->Equals(aLastVisitedURI, &same);
+    NS_ENSURE_SUCCESS(rv, rv);
+    if (same && IsRecentlyVisitedURI(aURI)) {
+      // Do not save refresh visits if we have visited this URI recently.
+      return NS_OK;
+    }
+  }
+
   if (!(aFlags & VisitFlags::TOP_LEVEL))
     return NS_OK;
 
   if (aFlags & VisitFlags::REDIRECT_SOURCE)
     return NS_OK;
 
   if (aFlags & VisitFlags::UNRECOVERABLE_ERROR)
     return NS_OK;
 
   nsAutoCString uri;
   rv = aURI->GetSpec(uri);
   if (NS_FAILED(rv)) return rv;
   NS_ConvertUTF8toUTF16 uriString(uri);
   GeckoAppShell::MarkURIVisited(uriString);
+
+  AppendToRecentlyVisitedURIs(aURI);
+
+  // Finally, notify that we've been visited.
+  nsCOMPtr<nsIObserverService> obsService =
+    mozilla::services::GetObserverService();
+  if (obsService) {
+    obsService->NotifyObservers(aURI, NS_LINK_VISITED_EVENT_TOPIC, nullptr);
+  }
+
   return NS_OK;
 }
 
 NS_IMETHODIMP
 nsAndroidHistory::SetURITitle(nsIURI *aURI, const nsAString& aTitle)
 {
   // Silently return if URI is something we shouldn't add to DB.
   bool canAdd;
--- a/mobile/android/components/build/nsAndroidHistory.h
+++ b/mobile/android/components/build/nsAndroidHistory.h
@@ -9,16 +9,19 @@
 #include "IHistory.h"
 #include "nsDataHashtable.h"
 #include "nsTPriorityQueue.h"
 #include "nsIRunnable.h"
 
 #define NS_ANDROIDHISTORY_CID \
     {0xCCAA4880, 0x44DD, 0x40A7, {0xA1, 0x3F, 0x61, 0x56, 0xFC, 0x88, 0x2C, 0x0B}}
 
+// Max size of History::mRecentlyVisitedURIs
+#define RECENTLY_VISITED_URI_SIZE 8
+
 class nsAndroidHistory : public mozilla::IHistory, public nsIRunnable
 {
 public:
   NS_DECL_ISUPPORTS
   NS_DECL_IHISTORY
   NS_DECL_NSIRUNNABLE
 
   /**
@@ -31,11 +34,23 @@ public:
 
 private:
   static nsAndroidHistory* sHistory;
 
   nsDataHashtable<nsStringHashKey, nsTArray<mozilla::dom::Link *> *> mListeners;
   nsTPriorityQueue<nsString> mPendingURIs;
 
   nsresult CanAddURI(nsIURI* aURI, bool* canAdd);
+
+  /**
+   * mRecentlyVisitedURIs remembers URIs which are recently added to the DB,
+   * to avoid saving these locations repeatedly in a short period.
+   */
+  typedef nsAutoTArray<nsCOMPtr<nsIURI>, RECENTLY_VISITED_URI_SIZE>
+          RecentlyVisitedArray;
+  RecentlyVisitedArray mRecentlyVisitedURIs;
+  RecentlyVisitedArray::index_type mRecentlyVisitedURIsNextIndex;
+
+  void AppendToRecentlyVisitedURIs(nsIURI* aURI);
+  bool IsRecentlyVisitedURI(nsIURI* aURI);
 };
 
 #endif