Bug 1002567 - Support weighted snippets. r=bnicholson
authorMargaret Leibovic <margaret.leibovic@gmail.com>
Wed, 30 Apr 2014 14:38:02 -0700
changeset 181569 f84446d45985b104eafa8e8be253a00a177281f9
parent 181568 51c6a235e6214e21838bcbe5eed754ddf4c002cf
child 181570 4c2f39f0bcc2033c8dfdd0cfa4f32edd3d4daf72
push id272
push userpvanderbeken@mozilla.com
push dateMon, 05 May 2014 16:31:18 +0000
reviewersbnicholson
bugs1002567
milestone32.0a1
Bug 1002567 - Support weighted snippets. r=bnicholson
mobile/android/components/Snippets.js
mobile/android/modules/Home.jsm
--- a/mobile/android/components/Snippets.js
+++ b/mobile/android/components/Snippets.js
@@ -193,16 +193,17 @@ function updateBanner(messages) {
   messages.forEach(function(message) {
     // Don't add this message to the banner if it's not supposed to be shown in this country.
     if ("target_geo" in message && message.target_geo != gCountryCode) {
       return;
     }
     let id = Home.banner.add({
       text: message.text,
       icon: message.icon,
+      weight: message.weight,
       onclick: function() {
         let parentId = gChromeWin.BrowserApp.selectedTab.id;
         gChromeWin.BrowserApp.addTab(message.url, { parentId: parentId });
       },
       ondismiss: function() {
         // Remove this snippet from the banner, and store its id so we'll never show it again.
         Home.banner.remove(id);
         removeSnippet(message.id);
--- a/mobile/android/modules/Home.jsm
+++ b/mobile/android/modules/Home.jsm
@@ -11,16 +11,19 @@ const { classes: Cc, interfaces: Ci, uti
 
 Cu.import("resource://gre/modules/Services.jsm");
 Cu.import("resource://gre/modules/SharedPreferences.jsm");
 Cu.import("resource://gre/modules/Messaging.jsm");
 
 // Keep this in sync with the constant defined in PanelAuthCache.java
 const PREFS_PANEL_AUTH_PREFIX = "home_panels_auth_";
 
+// Default weight for a banner message.
+const DEFAULT_WEIGHT = 100;
+
 // See bug 915424
 function resolveGeckoURI(aURI) {
   if (!aURI)
     throw "Can't resolve an empty uri";
 
   if (aURI.startsWith("chrome://")) {
     let registry = Cc['@mozilla.org/chrome/chrome-registry;1'].getService(Ci["nsIChromeRegistry"]);
     return registry.convertChromeURL(Services.io.newURI(aURI, null, null)).spec;
@@ -44,55 +47,67 @@ function BannerMessage(options) {
   if ("onshown" in options && typeof options.onshown === "function")
     this.onshown = options.onshown;
 
   if ("onclick" in options && typeof options.onclick === "function")
     this.onclick = options.onclick;
 
   if ("ondismiss" in options && typeof options.ondismiss === "function")
     this.ondismiss = options.ondismiss;
+
+  let weight = parseInt(options.weight, 10);
+  this.weight = weight > 0 ? weight : DEFAULT_WEIGHT;
 }
 
 // We need this object to have access to the HomeBanner
 // private members without leaking it outside Home.jsm.
 let HomeBannerMessageHandlers;
 
 let HomeBanner = (function () {
   // Whether there is a "HomeBanner:Get" request we couldn't fulfill.
   let _pendingRequest = false;
 
   // Functions used to handle messages sent from Java.
   HomeBannerMessageHandlers = {
     "HomeBanner:Get": function handleBannerGet(data) {
-      if (!_sendBannerData()) {
+      if (Object.keys(_messages).length > 0) {
+        _sendBannerData();
+      } else {
         _pendingRequest = true;
       }
     }
   };
 
   // Holds the messages that will rotate through the banner.
   let _messages = {};
 
+  // Choose a random message from the set of messages, biasing towards those with higher weight.
+  // Weight logic copied from desktop snippets:
+  // https://github.com/mozilla/snippets-service/blob/7d80edb8b1cddaed075275c2fc7cdf69a10f4003/snippets/base/templates/base/includes/snippet_js.html#L119
   let _sendBannerData = function() {
-    let keys = Object.keys(_messages);
-    if (!keys.length) {
-      return false;
+    let totalWeight = 0;
+    for (let key in _messages) {
+      let message = _messages[key];
+      totalWeight += message.weight;
+      message.totalWeight = totalWeight;
     }
 
-    // Choose a message at random.
-    let randomId = keys[Math.floor(Math.random() * keys.length)];
-    let message = _messages[randomId];
-
-    sendMessageToJava({
-      type: "HomeBanner:Data",
-      id: message.id,
-      text: message.text,
-      iconURI: message.iconURI
-    });
-    return true;
+    let threshold = Math.random() * totalWeight;
+    for (let key in _messages) {
+      let message = _messages[key];
+      if (threshold < message.totalWeight) {
+        sendMessageToJava({
+          type: "HomeBanner:Data",
+          id: message.id,
+          text: message.text,
+          iconURI: message.iconURI
+        });
+        return;
+      }
+    }
   };
 
   let _handleShown = function(id) {
     let message = _messages[id];
     if (message.onshown)
       message.onshown();
   };