Bug 949913 - Don't store page refreshes as history visits. r=blassey, a=bajaj
authorMark Finkle <mfinkle@mozilla.com>
Mon, 16 Dec 2013 16:00:08 -0500
changeset 167876 0366c03687fa785b9d0f0e5fa889fa454923673e
parent 167875 ff7059bb9c3eba1750d6ae77f54b4f14edee225f
child 167877 9847fa0e68e48da26052b6d4bd057ceaf618e3ba
push id428
push userbbajaj@mozilla.com
push dateTue, 28 Jan 2014 00:16:25 +0000
treeherdermozilla-release@cd72a7ff3a75 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersblassey, bajaj
bugs949913
milestone27.0
Bug 949913 - Don't store page refreshes as history visits. r=blassey, a=bajaj
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;
 
@@ -76,46 +80,88 @@ 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;
 
   AndroidBridge *bridge = AndroidBridge::Bridge();
   if (bridge) {
     nsAutoCString uri;
     rv = aURI->GetSpec(uri);
     if (NS_FAILED(rv)) return rv;
     NS_ConvertUTF8toUTF16 uriString(uri);
     bridge->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.
--- 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