merge fx-team to mozilla-central a=merge
authorCarsten "Tomcat" Book <cbook@mozilla.com>
Fri, 13 Nov 2015 11:57:53 +0100
changeset 272415 0eaf345983b3afc2b426e25a3be93ebf0d93e6c1
parent 272413 0169fdac5d0e27dbcef865a771e8b6e32b441de8 (current diff)
parent 272414 4b2ec935bc99bc505776190210b11dfe552bd041 (diff)
child 272416 faf815a0fa9b052a38bce00c0c2aa1e2c9610936
push id67953
push usercbook@mozilla.com
push dateFri, 13 Nov 2015 13:36:33 +0000
treeherdermozilla-inbound@62fdebd5b3ea [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersmerge
milestone45.0a1
first release with
nightly linux32
0eaf345983b3 / 45.0a1 / 20151113030248 / files
nightly linux64
0eaf345983b3 / 45.0a1 / 20151113030248 / files
nightly mac
0eaf345983b3 / 45.0a1 / 20151113030248 / files
nightly win32
0eaf345983b3 / 45.0a1 / 20151113030248 / files
nightly win64
0eaf345983b3 / 45.0a1 / 20151113030248 / files
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
releases
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
merge fx-team to mozilla-central a=merge
--- a/mobile/android/base/DoorHangerPopup.java
+++ b/mobile/android/base/DoorHangerPopup.java
@@ -113,16 +113,18 @@ public class DoorHangerPopup extends Anc
         final String id = json.getString("value");
 
         final String typeString = json.optString("category");
         DoorHanger.Type doorhangerType = DoorHanger.Type.DEFAULT;
         if (DoorHanger.Type.LOGIN.toString().equals(typeString)) {
             doorhangerType = DoorHanger.Type.LOGIN;
         } else if (DoorHanger.Type.GEOLOCATION.toString().equals(typeString)) {
             doorhangerType = DoorHanger.Type.GEOLOCATION;
+        } else if (DoorHanger.Type.DESKTOPNOTIFICATION2.toString().equals(typeString)) {
+            doorhangerType = DoorHanger.Type.DESKTOPNOTIFICATION2;
         }
 
         final DoorhangerConfig config = new DoorhangerConfig(tabId, id, doorhangerType, this);
 
         config.setMessage(json.getString("message"));
         config.setOptions(json.getJSONObject("options"));
 
         final JSONArray buttonArray = json.getJSONArray("buttons");
new file mode 100644
index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..77e0be68918ab5baf207c128ecd90147576f9f47
GIT binary patch
literal 446
zc%17D@N?(olHy`uVBq!ia0vp^0YL1<!3-p&o0OA)RDOU@h%1oZv17-EjhokR+`Mz=
z&W#(lY}mAU<K`_u_WDg*wr$%6<O0dfn}G_p9y@jnD7YS|VB?Pe|Nn2?xCcnC-v|@|
z>e>P_XA?yGW*`YP5J+y`ynoZCZ5x2}=Iua{HtTsJKr2;Bg8YIRB;WrP3%cIJoh-VZ
zU3voN+G8qA;*58$%@BIBH2?Ou*CG~ymUBa_`hn_idAc};R4~51#+uaZAj0<W;N8b9
zKmM+d$ba?k`hA%P&8?;#i!WGvd^)7jR#7Ej*4xQ<Ny$l9;!&n!fAfz0jJq89Ca|yL
z@Y$gy*r*x4RB1x8)&&P<UK1ekbosnLG1KnL{Ck&r^1vB(27BQ~)^O2JOVbxTSYC5_
zi(twEGqtGvLq6Q+X6R43m&8~1ewD@c?~D@tbEap{Zf_{wesRY3kgNO-c46UNjuBN!
z6YhHPY>Mr6yyeKVDKq84;g`+J*3~eqTE@SrX{toZ{%cL)m)TQiyK%<(%5N!EwRt0w
X8I=0oFJhx2(3cFJu6{1-oD!M<;_%e%
new file mode 100644
index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..3c4ba474e38a405a5954e27ae6af774b8a6267ae
GIT binary patch
literal 611
zc%17D@N?(olHy`uVBq!ia0vp^6+oQN!3-n?GQS)KQqux_LR^9LhE1C{Y}&G8$By+I
zH*eas4M;*n)^FOfZQHgD8#iy>ydNyJWB>mB|NsBrxN!$acH`#tFl9jX>o;!QxN!?m
zEl~W}v134yt5>gX0CIr}wrl|!vSkZU3)n!AdXO$4ICJI<$hys&f$~7Zfr6ViZwHDz
zRu_E>beUmEkY6yv(sIea7C+ZKPnP*4Ql`zqq|)){*t@m2Cj{kx<9yBLwb=NE;4|gl
zKQ1e=_6GKFys|W3@c1_a1EaU6i(^Oy<J%jlNlO$ZSRP81mzU2!QU3q%(b({pXP3QZ
zIxqi#l_6+mjuBUw(QHq~4eQMp9WZ@Wy+Dq0mGi2F4bqxM6PNHr^3G9R**Mu{5s!4;
z?l8Ucu|H$9Wnv;eE(ukXh<OybG@)Q-`qbuwqVqyI**+^BZsV0U%ek>35yFW0;1g<l
z=4-rQtE~Sm(SLv6tNni?X_jLl>;EA@X&xWj@yak8i8&7<Iqy60NMFlW|I4UkVN`Dq
z)SPefu5BmVyy8WT{t-H&?}`{FmsXV9GS0|#-hEq=p{Ke%^UZXtZaa-{WtW}v&%6(N
zUBmF%T-(gmV0o^f&sOcGh4V!Y%CIZVxZ=SQ{JJBd%UAHs2HmEWWv&KaCM(T&?7%Wv
zsxu)=R?ugoW|QPLSA(nTINIuhST0L<B%E_sni1vB5}ebO&;~N>bbBn5L9zP{X_XbX
QfN{d$>FVdQ&MBb@0Kh6DLI3~&
new file mode 100644
index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..2a52dbd505d31f3f85a7fcf6a07a4537a16723e9
GIT binary patch
literal 391
zc%17D@N?(olHy`uVBq!ia0vp^Hb88_!3-p)ZO#q@Qpo{6A+A7r!^SOFuU`HC|Nq9#
zn>TFQvSHKa&6{@u1%d4K+qZArxMe+%v2pYI&D+6(K*qN98@C=ib_^&E(zS61NOmJo
zFG%~QP209^-MV@6{`DYpwgbiGu1mN9tx+fm@(X6T#KxHa@3zLlDutj6f1KA{44A;V
zmPzIBx7SZB<VB8I+RB};1ghQa>Eakt!T9z{sM8S#0fviRyLUhTH~q-nmuzK?YyX?i
z;+*!@YPZ7it-5bw=k#hH*Xxt9e$%y&`?sRQi|!4_L+5cs$E0=|n9u#dIe&xP>-kIG
zr9U{|b^pTSf9!ld48{V9lUJWPTtDwu>TCWt+v`<2@2DLqk_om5dMz>`ZRf|V$Nw}Q
z@3Zl)T)wKV<!6lV$^!}ITs~K{4K6P@uw@<7<~3YCq1qqLPE|bn?#Yi=rzULY)yS&6
aW9hS1cf$P5rM*DsGkCiCxvX<aXaWF#;KiQ+
--- a/mobile/android/base/widget/DefaultDoorHanger.java
+++ b/mobile/android/base/widget/DefaultDoorHanger.java
@@ -44,16 +44,22 @@ public class DefaultDoorHanger extends D
         if (sSpinnerTextColor == -1) {
             sSpinnerTextColor = ColorUtils.getColor(context, R.color.text_color_primary_disable_only);
         }
 
         switch (mType) {
             case GEOLOCATION:
                 mIcon.setImageResource(R.drawable.location);
                 mIcon.setVisibility(VISIBLE);
+                break;
+
+            case DESKTOPNOTIFICATION2:
+                mIcon.setImageResource(R.drawable.push_notification);
+                mIcon.setVisibility(VISIBLE);
+                break;
         }
 
         loadConfig(config);
     }
 
     @Override
     protected void loadConfig(DoorhangerConfig config) {
         final String message = config.getMessage();
--- a/mobile/android/base/widget/DoorHanger.java
+++ b/mobile/android/base/widget/DoorHanger.java
@@ -29,17 +29,18 @@ public abstract class DoorHanger extends
             case LOGIN:
                 return new LoginDoorHanger(context, config);
             case TRACKING:
                 return new ContentSecurityDoorHanger(context, config, type);
         }
         return new DefaultDoorHanger(context, config, type);
     }
 
-    public static enum Type { DEFAULT, LOGIN, TRACKING, GEOLOCATION }
+    // Doorhanger types created from Gecko are checked against enum strings to determine type.
+    public static enum Type { DEFAULT, LOGIN, TRACKING, GEOLOCATION, DESKTOPNOTIFICATION2 }
 
     public interface OnButtonClickListener {
         public void onButtonClick(JSONObject response, DoorHanger doorhanger);
     }
 
     private static final String LOGTAG = "GeckoDoorHanger";
 
     // Divider between doorhangers.
--- a/mobile/android/base/widget/DoorhangerConfig.java
+++ b/mobile/android/base/widget/DoorhangerConfig.java
@@ -1,15 +1,17 @@
 /* -*- Mode: Java; c-basic-offset: 4; tab-width: 20; indent-tabs-mode: nil; -*-
  * This Source Code Form is subject to the terms of the Mozilla Public
  * 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/. */
 
 package org.mozilla.gecko.widget;
 
+import android.util.Log;
+import org.json.JSONException;
 import org.json.JSONObject;
 
 import org.mozilla.gecko.widget.DoorHanger.Type;
 
 public class DoorhangerConfig {
 
     public static class Link {
         public final String label;
@@ -73,16 +75,26 @@ public class DoorhangerConfig {
     }
 
     public String getMessage() {
         return message;
     }
 
     public void setOptions(JSONObject options) {
         this.options = options;
+
+        // Set link if there is a link provided in options.
+        final JSONObject linkObj = options.optJSONObject("link");
+        if (linkObj != null) {
+            try {
+                setLink(linkObj.getString("label"), linkObj.getString("url"));
+            } catch (JSONException e) {
+                Log.e(LOGTAG, "Malformed link object in options");
+            }
+        }
     }
 
     public JSONObject getOptions() {
         return options;
     }
 
     public void setButton(String label, int callbackId, boolean isPositive) {
         final ButtonConfig buttonConfig = new ButtonConfig(label, callbackId);
--- a/mobile/android/chrome/content/PermissionsHelper.js
+++ b/mobile/android/chrome/content/PermissionsHelper.js
@@ -29,18 +29,18 @@ var PermissionsHelper = {
     },
     "offline-app": {
       label: "offlineApps.storeOfflineData",
       allowed: "offlineApps.allow",
       denied: "offlineApps.dontAllow2"
     },
     "desktop-notification": {
       label: "desktopNotification.useNotifications",
-      allowed: "desktopNotification.allow",
-      denied: "desktopNotification.dontAllow"
+      allowed: "desktopNotification2.allow",
+      denied: "desktopNotification2.dontAllow"
     },
     "plugins": {
       label: "clickToPlayPlugins.activatePlugins",
       allowed: "clickToPlayPlugins.activate",
       denied: "clickToPlayPlugins.dontActivate"
     },
     "native-intent": {
       label: "helperapps.openWithList2",
--- a/mobile/android/components/ContentPermissionPrompt.js
+++ b/mobile/android/components/ContentPermissionPrompt.js
@@ -7,17 +7,17 @@ const Cr = Components.results;
 const Cu = Components.utils;
 const Cc = Components.classes;
 
 Cu.import("resource://gre/modules/XPCOMUtils.jsm");
 Cu.import("resource://gre/modules/Services.jsm");
 
 const kEntities = {
   "contacts": "contacts",
-  "desktop-notification": "desktopNotification",
+  "desktop-notification": "desktopNotification2",
   "device-storage:music": "deviceStorageMusic",
   "device-storage:pictures": "deviceStoragePictures",
   "device-storage:sdcard": "deviceStorageSdcard",
   "device-storage:videos": "deviceStorageVideos",
   "geolocation": "geolocation",
 };
 
 // For these types, prompt for permission if action is unknown.
@@ -96,42 +96,53 @@ ContentPermissionPrompt.prototype = {
       return;
 
     let browserBundle = Services.strings.createBundle("chrome://browser/locale/browser.properties");
     let entityName = kEntities[perm.type];
 
     let buttons = [{
       label: browserBundle.GetStringFromName(entityName + ".dontAllow"),
       callback: function(aChecked) {
-        // If the user checked "Don't ask again", make a permanent exception
-        if (aChecked)
+        // If the user checked "Don't ask again" or this is a desktopNotification, make a permanent exception
+        if (aChecked || entityName == "desktopNotification2")
           Services.perms.addFromPrincipal(request.principal, access, Ci.nsIPermissionManager.DENY_ACTION);
 
         request.cancel();
       }
     },
     {
       label: browserBundle.GetStringFromName(entityName + ".allow"),
       callback: function(aChecked) {
-        // If the user checked "Don't ask again", make a permanent exception
-        if (aChecked) {
+        // If the user checked "Don't ask again" or this is a desktopNotification, make a permanent exception
+        if (aChecked || entityName == "desktopNotification2") {
           Services.perms.addFromPrincipal(request.principal, access, Ci.nsIPermissionManager.ALLOW_ACTION);
-        } else if (isApp || entityName == "desktopNotification") {
-          // Otherwise allow the permission for the current session (if the request comes from an app or if it's a desktop-notification request)
+        } else if (isApp) {
+          // Otherwise allow the permission for the current session if the request comes from an app
           Services.perms.addFromPrincipal(request.principal, access, Ci.nsIPermissionManager.ALLOW_ACTION, Ci.nsIPermissionManager.EXPIRE_SESSION);
         }
 
         request.allow();
       },
       positive: true
     }];
 
     let requestor = chromeWin.BrowserApp.manifest ? "'" + chromeWin.BrowserApp.manifest.name + "'" : request.principal.URI.host;
     let message = browserBundle.formatStringFromName(entityName + ".ask", [requestor], 1);
-    let options = { checkbox: browserBundle.GetStringFromName(entityName + ".dontAskAgain") };
+    // desktopNotification doesn't have a checkbox
+    let options;
+    if (entityName == "desktopNotification2") {
+      options = {
+        link: {
+          label: browserBundle.GetStringFromName("doorhanger.learnMore"),
+          url: "https://www.mozilla.org/firefox/push/"
+        }
+      };
+    } else {
+      options = { checkbox: browserBundle.GetStringFromName(entityName + ".dontAskAgain") };
+    }
 
     chromeWin.NativeWindow.doorhanger.show(message, entityName + request.principal.URI.host, buttons, tab.id, options, entityName.toUpperCase());
   }
 };
 
 
 //module initialization
 this.NSGetFactory = XPCOMUtils.generateNSGetFactory([ContentPermissionPrompt]);
--- a/mobile/android/locales/en-US/chrome/browser.properties
+++ b/mobile/android/locales/en-US/chrome/browser.properties
@@ -71,16 +71,17 @@ addonLocalError-4=#1 could not be instal
 addonLocalError-5=This add-on could not be installed because it has not been verified.
 addonErrorIncompatible=#1 could not be installed because it is not compatible with #3 #4.
 addonErrorBlocklisted=#1 could not be installed because it has a high risk of causing stability or security problems.
 
 # Notifications
 notificationRestart.normal=Restart to complete changes.
 notificationRestart.blocked=Unsafe add-ons installed. Restart to disable.
 notificationRestart.button=Restart
+doorhanger.learnMore=Learn more
 
 # Popup Blocker
 
 # LOCALIZATION NOTE (popup.message): Semicolon-separated list of plural forms.
 # #1 is brandShortName and #2 is the number of pop-ups blocked.
 popup.message=#1 prevented this site from opening a pop-up window. Would you like to show it?;#1 prevented this site from opening #2 pop-up windows. Would you like to show them?
 popup.dontAskAgain=Don't ask again for this site
 popup.show=Show
@@ -115,25 +116,22 @@ geolocation.ask=Share your location with
 # LOCALIZATION NOTE (geolocation.shareLocation): Label that will be used in
 # site settings dialog.
 geolocation.shareLocation=Share Location
 # LOCALIZATION NOTE (geolocation.dontAskAgain): This label appears next to a
 # checkbox to indicate whether or not the user wants to make a permanent decision.
 geolocation.dontAskAgain=Don't ask again for this site
 
 # Desktop notification UI
-desktopNotification.allow=Allow
-desktopNotification.dontAllow=Don't allow
-desktopNotification.ask=Allow %S to use notifications?
+desktopNotification2.allow=Always
+desktopNotification2.dontAllow=Never
+desktopNotification2.ask=Would you like to receive notifications from this site?
 # LOCALIZATION NOTE (desktopNotification.useNotifications): Label that will be
 # used in site settings dialog.
 desktopNotification.useNotifications=Use Notifications
-# LOCALIZATION NOTE (desktopNotification.dontAskAgain): This label appears next to a
-# checkbox to indicate whether or not the user wants to make a permanent decision.
-desktopNotification.dontAskAgain=Don't ask again for this site
 
 # Imageblocking
 imageblocking.downloadedImage=Image unblocked
 imageblocking.showAllImages=Show All
 
 # Contacts API
 contacts.allow=Allow
 contacts.dontAllow=Don't allow