Bug 1238712 - Move duplicated shell-service code to a shared JSM. r?gijs draft
authorJared Wein <jwein@mozilla.com>
Wed, 13 Jan 2016 00:57:35 -0500
changeset 321188 26df22dab4e31b086cb7613891b7b0597027a28b
parent 320165 ea01aa74be131267e98f034d115df035bd86cd9d
child 512872 cec12699664fc1cbcb2a3e3c7ec42d1735897d11
push id9348
push userjwein@mozilla.com
push dateWed, 13 Jan 2016 05:59:10 +0000
reviewersgijs
bugs1238712
milestone46.0a1
Bug 1238712 - Move duplicated shell-service code to a shared JSM. r?gijs
browser/base/content/utilityOverlay.js
browser/components/nsBrowserContentHandler.js
browser/components/nsBrowserGlue.js
browser/components/preferences/in-content/main.js
browser/components/shell/ShellService.jsm
browser/components/shell/moz.build
browser/components/shell/nsGNOMEShellService.cpp
browser/components/shell/nsGNOMEShellService.h
browser/components/shell/nsIGNOMEShellService.idl
browser/components/shell/nsIMacShellService.idl
browser/components/shell/nsIShellService.idl
browser/components/shell/nsIWindowsShellService.idl
browser/components/shell/nsMacShellService.cpp
browser/components/shell/nsMacShellService.h
browser/components/shell/nsSetDefaultBrowser.js
browser/components/shell/nsWindowsShellService.cpp
browser/components/shell/nsWindowsShellService.h
browser/components/shell/test/browser_633221.js
toolkit/components/telemetry/TelemetryEnvironment.jsm
--- a/browser/base/content/utilityOverlay.js
+++ b/browser/base/content/utilityOverlay.js
@@ -5,16 +5,19 @@
 
 // Services = object with smart getters for common XPCOM services
 Components.utils.import("resource://gre/modules/AppConstants.jsm");
 Components.utils.import("resource://gre/modules/Services.jsm");
 Components.utils.import("resource://gre/modules/XPCOMUtils.jsm");
 Components.utils.import("resource://gre/modules/PrivateBrowsingUtils.jsm");
 Components.utils.import("resource:///modules/RecentWindow.jsm");
 
+XPCOMUtils.defineLazyModuleGetter(this, "ShellService",
+                                  "resource:///modules/ShellService.jsm");
+
 XPCOMUtils.defineLazyServiceGetter(this, "aboutNewTabService",
                                    "@mozilla.org/browser/aboutnewtab-service;1",
                                    "nsIAboutNewTabService");
 
 this.__defineGetter__("BROWSER_NEW_TAB_URL", () => {
   if (PrivateBrowsingUtils.isWindowPrivate(window) &&
       !PrivateBrowsingUtils.permanentPrivateBrowsing &&
       !aboutNewTabService.overridden) {
@@ -449,25 +452,20 @@ function gatherTextUnder ( root )
   }
   // Strip leading and tailing whitespace.
   text = text.trim();
   // Compress remaining whitespace.
   text = text.replace( /\s+/g, " " );
   return text;
 }
 
+// This function exists for legacy reasons.
 function getShellService()
 {
-  var shell = null;
-  try {
-    shell = Components.classes["@mozilla.org/browser/shell-service;1"]
-      .getService(Components.interfaces.nsIShellService);
-  } catch (e) {
-  }
-  return shell;
+  return ShellService;
 }
 
 function isBidiEnabled() {
   // first check the pref.
   if (getBoolPref("bidi.browser.ui", false))
     return true;
 
   // then check intl.uidirection.<locale>
--- a/browser/components/nsBrowserContentHandler.js
+++ b/browser/components/nsBrowserContentHandler.js
@@ -7,16 +7,18 @@ Components.utils.importGlobalProperties(
 Components.utils.import("resource://gre/modules/XPCOMUtils.jsm");
 Components.utils.import("resource://gre/modules/Services.jsm");
 Components.utils.import("resource://gre/modules/AppConstants.jsm");
 
 XPCOMUtils.defineLazyModuleGetter(this, "PrivateBrowsingUtils",
                                   "resource://gre/modules/PrivateBrowsingUtils.jsm");
 XPCOMUtils.defineLazyModuleGetter(this, "RecentWindow",
                                   "resource:///modules/RecentWindow.jsm");
+XPCOMUtils.defineLazyModuleGetter(this, "ShellService",
+                                  "resource:///modules/ShellService.jsm");
 XPCOMUtils.defineLazyServiceGetter(this, "WindowsUIUtils",
                                    "@mozilla.org/windows-ui-utils;1", "nsIWindowsUIUtils");
 
 const nsISupports            = Components.interfaces.nsISupports;
 
 const nsIBrowserDOMWindow    = Components.interfaces.nsIBrowserDOMWindow;
 const nsIBrowserHandler      = Components.interfaces.nsIBrowserHandler;
 const nsIBrowserHistory      = Components.interfaces.nsIBrowserHistory;
@@ -655,19 +657,17 @@ nsBrowserContentHandler.prototype = {
       var urlParam = cmdLine.getArgument(urlFlagIdx + 1);
       if (cmdLine.length != urlFlagIdx + 2 || /firefoxurl:/.test(urlParam))
         throw NS_ERROR_ABORT;
       var isDefault = false;
       try {
         var url = Services.urlFormatter.formatURLPref("app.support.baseURL") +
                   "win10-default-browser";
         if (urlParam == url) {
-          var shellSvc = Components.classes["@mozilla.org/browser/shell-service;1"]
-                                   .getService(Components.interfaces.nsIShellService);
-          isDefault = shellSvc.isDefaultBrowser(false, false);
+          isDefault = ShellService.isDefaultBrowser(false, false);
         }
       } catch (ex) {}
       if (isDefault) {
         // Firefox is already the default HTTP handler.
         // We don't have to show the instruction page.
         throw NS_ERROR_ABORT;
       }
       cmdLine.handleFlag("osint", false)
--- a/browser/components/nsBrowserGlue.js
+++ b/browser/components/nsBrowserGlue.js
@@ -147,26 +147,16 @@ XPCOMUtils.defineLazyModuleGetter(this, 
 
 XPCOMUtils.defineLazyModuleGetter(this, "TabCrashHandler",
                                   "resource:///modules/ContentCrashHandlers.jsm");
 #ifdef MOZ_CRASHREPORTER
 XPCOMUtils.defineLazyModuleGetter(this, "PluginCrashReporter",
                                   "resource:///modules/ContentCrashHandlers.jsm");
 #endif
 
-XPCOMUtils.defineLazyGetter(this, "ShellService", function() {
-  try {
-    return Cc["@mozilla.org/browser/shell-service;1"].
-           getService(Ci.nsIShellService);
-  }
-  catch(ex) {
-    return null;
-  }
-});
-
 XPCOMUtils.defineLazyGetter(this, "gBrandBundle", function() {
   return Services.strings.createBundle('chrome://branding/locale/brand.properties');
 });
 
 XPCOMUtils.defineLazyGetter(this, "gBrowserBundle", function() {
   return Services.strings.createBundle('chrome://browser/locale/browser.properties');
 });
 
@@ -184,16 +174,19 @@ XPCOMUtils.defineLazyModuleGetter(this, 
                                   "resource://gre/modules/AddonWatcher.jsm");
 
 XPCOMUtils.defineLazyModuleGetter(this, "LightweightThemeManager",
                                   "resource://gre/modules/LightweightThemeManager.jsm");
 
 XPCOMUtils.defineLazyModuleGetter(this, "ExtensionManagement",
                                   "resource://gre/modules/ExtensionManagement.jsm");
 
+XPCOMUtils.defineLazyModuleGetter(this, "ShellService",
+                                  "resource:///modules/ShellService.jsm");
+
 XPCOMUtils.defineLazyServiceGetter(this, "WindowsUIUtils",
                                    "@mozilla.org/windows-ui-utils;1", "nsIWindowsUIUtils");
 
 XPCOMUtils.defineLazyServiceGetter(this, "AlertsService",
                                    "@mozilla.org/alerts-service;1", "nsIAlertsService");
 
 const ABOUT_NEWTAB = "about:newtab";
 
--- a/browser/components/preferences/in-content/main.js
+++ b/browser/components/preferences/in-content/main.js
@@ -1,15 +1,16 @@
 /* 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/. */
 
 Components.utils.import("resource://gre/modules/Downloads.jsm");
 Components.utils.import("resource://gre/modules/FileUtils.jsm");
 Components.utils.import("resource://gre/modules/Task.jsm");
+Components.utils.import("resource:///modules/ShellService.jsm");
 Components.utils.import("resource:///modules/TransientPrefs.jsm");
 #ifdef E10S_TESTING_ONLY
 XPCOMUtils.defineLazyModuleGetter(this, "UpdateUtils",
                                   "resource://gre/modules/UpdateUtils.jsm");
 #endif
 
 var gMainPane = {
   /**
new file mode 100644
--- /dev/null
+++ b/browser/components/shell/ShellService.jsm
@@ -0,0 +1,86 @@
+/* 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/. */
+
+"use strict";
+
+this.EXPORTED_SYMBOLS = ["ShellService"];
+
+const { classes: Cc, interfaces: Ci, utils: Cu, results: Cr } = Components;
+
+Cu.import("resource://gre/modules/AppConstants.jsm");
+Cu.import("resource://gre/modules/Services.jsm");
+Cu.import("resource://gre/modules/XPCOMUtils.jsm");
+
+/**
+ * Internal functionality to save and restore the docShell.allow* properties.
+ */
+let ShellServiceInternal = {
+  /**
+   * Used to determine whether or not to offer "Set as desktop background"
+   * functionality. Even if shell service is available it is not
+   * guaranteed that it is able to set the background for every desktop
+   * which is especially true for Linux with its many different desktop
+   * environments.
+   */
+  get canSetDesktopBackground() {
+    if (AppConstants.platform == "win" ||
+        AppConstants.platform == "macosx") {
+      return true;
+    }
+
+    if (AppConstants.platform == "linux") {
+      if (this.shellService) {
+        let linuxShellService = this.shellService
+                                    .QueryInterface(Ci.nsIGNOMEShellService);
+        return linuxShellService.canSetDesktopBackground;
+      }
+    }
+
+    return false;
+  },
+
+  /**
+   * Used to determine whether or not to show a "Set Default Browser"
+   * query dialog. This attribute is true if the application is starting
+   * up and "browser.shell.checkDefaultBrowser" is true, otherwise it
+   * is false.
+   */
+  _checkedThisSession: false,
+  get shouldCheckDefaultBrowser() {
+    // If we've already checked, the browser has been started and this is a
+    // new window open, and we don't want to check again.
+    if (this._checkedThisSession) {
+      return false;
+    }
+
+    return Services.prefs.getBoolPref("browser.shell.checkDefaultBrowser");
+  },
+  set shouldCheckDefaultBrowser(shouldCheck) {
+    Services.prefs.setBoolPref("browser.shell.checkDefaultBrowser", !!shouldCheck);
+  },
+  isDefaultBrowser(startupCheck, forAllTypes) {
+    // If this is the first browser window, maintain internal state that we've
+    // checked this session (so that subsequent window opens don't show the
+    // default browser dialog).
+    if (startupCheck) {
+      this._checkedThisSession = true;
+    }
+    if (this.shellService) {
+      return this.shellService.isDefaultBrowser(startupCheck, forAllTypes);
+    }
+  }
+};
+
+XPCOMUtils.defineLazyServiceGetter(ShellServiceInternal, "shellService",
+  "@mozilla.org/browser/shell-service;1", Ci.nsIShellService);
+
+/**
+ * The external API exported by this module.
+ */
+this.ShellService = new Proxy(ShellServiceInternal, {
+  get(target, name) {
+    return name in target ? target[name] :
+                            target.shellService[name];
+  }
+});
--- a/browser/components/shell/moz.build
+++ b/browser/components/shell/moz.build
@@ -16,16 +16,20 @@ XPIDL_SOURCES += [
 if CONFIG['OS_ARCH'] == 'WINNT':
     XPIDL_SOURCES += [
         'nsIWindowsShellService.idl',
     ]
 elif CONFIG['MOZ_WIDGET_TOOLKIT'] == 'cocoa':
     XPIDL_SOURCES += [
         'nsIMacShellService.idl',
     ]
+elif CONFIG['MOZ_WIDGET_GTK']:
+    XPIDL_SOURCES += [
+        'nsIGNOMEShellService.idl',
+    ]
 
 XPIDL_MODULE = 'shellservice'
 
 if CONFIG['OS_ARCH'] == 'WINNT':
     SOURCES += [
         'nsWindowsShellService.cpp',
     ]
 elif CONFIG['MOZ_WIDGET_TOOLKIT'] == 'cocoa':
@@ -40,16 +44,20 @@ elif CONFIG['MOZ_WIDGET_GTK']:
 if SOURCES:
     FINAL_LIBRARY = 'browsercomps'
 
 EXTRA_COMPONENTS += [
     'nsSetDefaultBrowser.js',
     'nsSetDefaultBrowser.manifest',
 ]
 
+EXTRA_JS_MODULES += [
+    'ShellService.jsm',
+]
+
 for var in ('MOZ_APP_NAME', 'MOZ_APP_VERSION'):
     DEFINES[var] = '"%s"' % CONFIG[var]
 
 CXXFLAGS += CONFIG['TK_CFLAGS']
 
 with Files('**'):
     BUG_COMPONENT = ('Firefox', 'Shell Integration')
 
--- a/browser/components/shell/nsGNOMEShellService.cpp
+++ b/browser/components/shell/nsGNOMEShellService.cpp
@@ -112,17 +112,17 @@ nsGNOMEShellService::Init()
   nsCOMPtr<nsIFile> appPath;
   rv = dirSvc->Get(XRE_EXECUTABLE_FILE, NS_GET_IID(nsIFile),
                    getter_AddRefs(appPath));
   NS_ENSURE_SUCCESS(rv, rv);
 
   return appPath->GetNativePath(mAppPath);
 }
 
-NS_IMPL_ISUPPORTS(nsGNOMEShellService, nsIShellService)
+NS_IMPL_ISUPPORTS(nsGNOMEShellService, nsIGNOMEShellService, nsIShellService)
 
 bool
 nsGNOMEShellService::GetAppPathFromLauncher()
 {
   gchar *tmp;
 
   const char *launcher = PR_GetEnv("MOZ_APP_LAUNCHER");
   if (!launcher)
@@ -196,18 +196,16 @@ nsGNOMEShellService::CheckHandlerMatches
 }
 
 NS_IMETHODIMP
 nsGNOMEShellService::IsDefaultBrowser(bool aStartupCheck,
                                       bool aForAllTypes,
                                       bool* aIsDefaultBrowser)
 {
   *aIsDefaultBrowser = false;
-  if (aStartupCheck)
-    mCheckedThisSession = true;
 
   nsCOMPtr<nsIGConfService> gconf = do_GetService(NS_GCONFSERVICE_CONTRACTID);
   nsCOMPtr<nsIGIOService> giovfs = do_GetService(NS_GIOSERVICE_CONTRACTID);
 
   bool enabled;
   nsAutoCString handler;
   nsCOMPtr<nsIGIOMimeApp> gioApp;
 
@@ -321,47 +319,16 @@ nsGNOMEShellService::SetDefaultBrowser(b
     // before it is silenced.
     (void) prefs->SetIntPref(PREF_DEFAULTBROWSERCHECKCOUNT, 0);
   }
 
   return NS_OK;
 }
 
 NS_IMETHODIMP
-nsGNOMEShellService::GetShouldCheckDefaultBrowser(bool* aResult)
-{
-  // If we've already checked, the browser has been started and this is a 
-  // new window open, and we don't want to check again.
-  if (mCheckedThisSession) {
-    *aResult = false;
-    return NS_OK;
-  }
-
-  nsresult rv;
-  nsCOMPtr<nsIPrefBranch> prefs(do_GetService(NS_PREFSERVICE_CONTRACTID, &rv));
-  if (NS_FAILED(rv)) {
-    return rv;
-  }
-
-  return prefs->GetBoolPref(PREF_CHECKDEFAULTBROWSER, aResult);
-}
-
-NS_IMETHODIMP
-nsGNOMEShellService::SetShouldCheckDefaultBrowser(bool aShouldCheck)
-{
-  nsresult rv;
-  nsCOMPtr<nsIPrefBranch> prefs(do_GetService(NS_PREFSERVICE_CONTRACTID, &rv));
-  if (NS_FAILED(rv)) {
-    return rv;
-  }
-
-  return prefs->SetBoolPref(PREF_CHECKDEFAULTBROWSER, aShouldCheck);
-}
-
-NS_IMETHODIMP
 nsGNOMEShellService::GetCanSetDesktopBackground(bool* aResult)
 {
   // setting desktop background is currently only supported
   // for Gnome or desktops using the same GSettings and GConf keys
   const char* gnomeSession = getenv("GNOME_DESKTOP_SESSION_ID");
   if (gnomeSession) {
     *aResult = true;
   } else {
--- a/browser/components/shell/nsGNOMEShellService.h
+++ b/browser/components/shell/nsGNOMEShellService.h
@@ -1,36 +1,36 @@
 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
 /* 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/. */
 
 #ifndef nsgnomeshellservice_h____
 #define nsgnomeshellservice_h____
 
-#include "nsIShellService.h"
+#include "nsIGNOMEShellService.h"
 #include "nsStringAPI.h"
 #include "mozilla/Attributes.h"
 
-class nsGNOMEShellService final : public nsIShellService
+class nsGNOMEShellService final : public nsIGNOMEShellService
 {
 public:
-  nsGNOMEShellService() : mCheckedThisSession(false), mAppIsInPath(false) { }
+  nsGNOMEShellService() : mAppIsInPath(false) { }
 
   NS_DECL_ISUPPORTS
   NS_DECL_NSISHELLSERVICE
+  NS_DECL_NSIGNOMESHELLSERVICE
 
   nsresult Init();
 
 private:
   ~nsGNOMEShellService() {}
 
   bool KeyMatchesAppName(const char *aKeyValue) const;
   bool CheckHandlerMatchesAppName(const nsACString& handler) const;
 
   bool GetAppPathFromLauncher();
-  bool mCheckedThisSession;
   bool mUseLocaleFilenames;
   nsCString    mAppPath;
   bool mAppIsInPath;
 };
 
 #endif // nsgnomeshellservice_h____
new file mode 100644
--- /dev/null
+++ b/browser/components/shell/nsIGNOMEShellService.idl
@@ -0,0 +1,19 @@
+/* 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/. */
+
+#include "nsIShellService.idl"
+
+[scriptable, uuid(2ce5c803-edcd-443d-98eb-ceba86d02d13)]
+interface nsIGNOMEShellService : nsIShellService
+{
+  /**
+   * Used to determine whether or not to offer "Set as desktop background"
+   * functionality. Even if shell service is available it is not
+   * guaranteed that it is able to set the background for every desktop
+   * which is especially true for Linux with its many different desktop
+   * environments.
+   */
+  readonly attribute boolean canSetDesktopBackground;
+};
+
--- a/browser/components/shell/nsIMacShellService.idl
+++ b/browser/components/shell/nsIMacShellService.idl
@@ -1,15 +1,15 @@
 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
 /* 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/. */
 
 #include "nsIShellService.idl"
 
-[scriptable, uuid(291a27cd-ef4c-46c6-a2f8-83182498167e)]
+[scriptable, uuid(387fdc80-0077-4b60-a0d9-d9e80a83ba64)]
 interface nsIMacShellService : nsIShellService
 {
   const long APPLICATION_KEYCHAIN_ACCESS  = 2;
   const long APPLICATION_NETWORK          = 3;
   const long APPLICATION_DESKTOP          = 4;
 };
 
--- a/browser/components/shell/nsIShellService.idl
+++ b/browser/components/shell/nsIShellService.idl
@@ -3,17 +3,17 @@
  * 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 "nsISupports.idl"
 
 interface nsIDOMElement;
 interface nsIFile;
 
-[scriptable, uuid(53f4bc4a-5b86-4643-8e67-4907ecbab34c)]
+[scriptable, uuid(2d1a95e4-5bd8-4eeb-b0a8-c1455fd2a357)]
 interface nsIShellService : nsISupports
 {
   /**
    * Determines whether or not Firefox is the "Default Browser."
    * This is simply whether or not Firefox is registered to handle
    * http links.
    *
    * @param aStartupCheck true if this is the check being performed
@@ -33,33 +33,16 @@ interface nsIShellService : nsISupports
    *                       additional protocols (ftp, chrome etc)
    *                       and web documents (.html, .xhtml etc).
    * @param aForAllUsers   Whether or not Firefox should attempt
    *                       to become the default browser for all
    *                       users on a multi-user system. 
    */
   void setDefaultBrowser(in boolean aClaimAllTypes, in boolean aForAllUsers);
 
-  /**
-   * Used to determine whether or not to show a "Set Default Browser"
-   * query dialog. This attribute is true if the application is starting
-   * up and "browser.shell.checkDefaultBrowser" is true, otherwise it
-   * is false.
-   */
-  attribute boolean shouldCheckDefaultBrowser;
-
-  /**
-   * Used to determine whether or not to offer "Set as desktop background"
-   * functionality. Even if shell service is available it is not
-   * guaranteed that it is able to set the background for every desktop
-   * which is especially true for Linux with its many different desktop
-   * environments.
-   */
-  readonly attribute boolean canSetDesktopBackground;
-
   /** 
    * Flags for positioning/sizing of the Desktop Background image.
    */
   const long BACKGROUND_TILE      = 1;
   const long BACKGROUND_STRETCH   = 2;
   const long BACKGROUND_CENTER    = 3;
   const long BACKGROUND_FILL      = 4;
   const long BACKGROUND_FIT       = 5;
--- a/browser/components/shell/nsIWindowsShellService.idl
+++ b/browser/components/shell/nsIWindowsShellService.idl
@@ -1,16 +1,16 @@
 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
 /* 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/. */
 
 #include "nsIShellService.idl"
 
-[scriptable, uuid(13f20725-4fd5-431f-90a1-525ab31755b1)]
+[scriptable, uuid(f8a26b94-49e5-4441-8fbc-315e0b4f22ef)]
 interface nsIWindowsShellService : nsIShellService
 {
     /**
      * Provides the shell service an opportunity to do some Win7+ shortcut
      * maintenance needed on initial startup of the browser.
      */
     void shortcutMaintenance();
 };
--- a/browser/components/shell/nsMacShellService.cpp
+++ b/browser/components/shell/nsMacShellService.cpp
@@ -52,22 +52,16 @@ nsMacShellService::IsDefaultBrowser(bool
   // Get the default http handler's bundle ID (or nullptr if it has not been
   // explicitly set)
   CFStringRef defaultBrowserID = ::LSCopyDefaultHandlerForURLScheme(CFSTR("http"));
   if (defaultBrowserID) {
     *aIsDefaultBrowser = ::CFStringCompare(firefoxID, defaultBrowserID, 0) == kCFCompareEqualTo;
     ::CFRelease(defaultBrowserID);
   }
 
-  // If this is the first browser window, maintain internal state that we've
-  // checked this session (so that subsequent window opens don't show the 
-  // default browser dialog).
-  if (aStartupCheck)
-    mCheckedThisSession = true;
-
   return NS_OK;
 }
 
 NS_IMETHODIMP
 nsMacShellService::SetDefaultBrowser(bool aClaimAllTypes, bool aForAllUsers)
 {
   // Note: We don't support aForAllUsers on Mac OS X.
 
@@ -99,54 +93,16 @@ nsMacShellService::SetDefaultBrowser(boo
     // before it is silenced.
     (void) prefs->SetIntPref(PREF_DEFAULTBROWSERCHECKCOUNT, 0);
   }
 
   return NS_OK;
 }
 
 NS_IMETHODIMP
-nsMacShellService::GetShouldCheckDefaultBrowser(bool* aResult)
-{
-  // If we've already checked, the browser has been started and this is a 
-  // new window open, and we don't want to check again.
-  if (mCheckedThisSession) {
-    *aResult = false;
-    return NS_OK;
-  }
-
-  nsresult rv;
-  nsCOMPtr<nsIPrefBranch> prefs(do_GetService(NS_PREFSERVICE_CONTRACTID, &rv));
-  if (NS_FAILED(rv)) {
-    return rv;
-  }
-
-  return prefs->GetBoolPref(PREF_CHECKDEFAULTBROWSER, aResult);
-}
-
-NS_IMETHODIMP
-nsMacShellService::SetShouldCheckDefaultBrowser(bool aShouldCheck)
-{
-  nsresult rv;
-  nsCOMPtr<nsIPrefBranch> prefs(do_GetService(NS_PREFSERVICE_CONTRACTID, &rv));
-  if (NS_FAILED(rv)) {
-    return rv;
-  }
-
-  return prefs->SetBoolPref(PREF_CHECKDEFAULTBROWSER, aShouldCheck);
-}
-
-NS_IMETHODIMP
-nsMacShellService::GetCanSetDesktopBackground(bool* aResult)
-{
-  *aResult = true;
-  return NS_OK;
-}
-
-NS_IMETHODIMP
 nsMacShellService::SetDesktopBackground(nsIDOMElement* aElement, 
                                         int32_t aPosition)
 {
   // Note: We don't support aPosition on OS X.
 
   // Get the image URI:
   nsresult rv;
   nsCOMPtr<nsIImageLoadingContent> imageContent = do_QueryInterface(aElement,
--- a/browser/components/shell/nsMacShellService.h
+++ b/browser/components/shell/nsMacShellService.h
@@ -10,25 +10,23 @@
 #include "nsIWebProgressListener.h"
 #include "nsIFile.h"
 #include "nsCOMPtr.h"
 
 class nsMacShellService : public nsIMacShellService,
                           public nsIWebProgressListener
 {
 public:
-  nsMacShellService() : mCheckedThisSession(false) {};
+  nsMacShellService() {};
 
   NS_DECL_ISUPPORTS
   NS_DECL_NSISHELLSERVICE
   NS_DECL_NSIMACSHELLSERVICE
   NS_DECL_NSIWEBPROGRESSLISTENER
 
 protected:
   virtual ~nsMacShellService() {};
 
 private:
   nsCOMPtr<nsIFile> mBackgroundFile;
-
-  bool      mCheckedThisSession;
 };
 
 #endif // nsmacshellservice_h____
--- a/browser/components/shell/nsSetDefaultBrowser.js
+++ b/browser/components/shell/nsSetDefaultBrowser.js
@@ -1,29 +1,28 @@
 /* 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/. */
 
-/* 
+/*
  * --setDefaultBrowser commandline handler
  * Makes the current executable the "default browser".
  */
 
 const Cc = Components.classes;
 const Ci = Components.interfaces;
+Components.utils.import("resource:///modules/ShellService.jsm");
 Components.utils.import("resource://gre/modules/XPCOMUtils.jsm");
 
 function nsSetDefaultBrowser() {}
 
 nsSetDefaultBrowser.prototype = {
   handle: function nsSetDefault_handle(aCmdline) {
     if (aCmdline.handleFlag("setDefaultBrowser", false)) {
-      var shell = Cc["@mozilla.org/browser/shell-service;1"].
-                  getService(Ci.nsIShellService);
-      shell.setDefaultBrowser(true, true);
+      ShellService.setDefaultBrowser(true, true);
     }
   },
 
   helpInfo: "  --setDefaultBrowser Set this app as the default browser.\n",
 
   classID: Components.ID("{F57899D0-4E2C-4ac6-9E29-50C736103B0C}"),
   QueryInterface: XPCOMUtils.generateQI([Ci.nsICommandLineHandler]),
 };
--- a/browser/components/shell/nsWindowsShellService.cpp
+++ b/browser/components/shell/nsWindowsShellService.cpp
@@ -603,22 +603,16 @@ nsWindowsShellService::IsDefaultBrowserV
   return true;
 }
 
 NS_IMETHODIMP
 nsWindowsShellService::IsDefaultBrowser(bool aStartupCheck,
                                         bool aForAllTypes,
                                         bool* aIsDefaultBrowser)
 {
-  // If this is the first browser window, maintain internal state that we've
-  // checked this session (so that subsequent window opens don't show the
-  // default browser dialog).
-  if (aStartupCheck)
-    mCheckedThisSession = true;
-
   // Assume we're the default unless one of the several checks below tell us
   // otherwise.
   *aIsDefaultBrowser = true;
 
   wchar_t exePath[MAX_BUF];
   if (!::GetModuleFileNameW(0, exePath, MAX_BUF))
     return NS_ERROR_FAILURE;
 
@@ -802,23 +796,16 @@ nsWindowsShellService::IsDefaultBrowser(
     if (REG_FAILED(res)) {
       *aIsDefaultBrowser = false;
     }
   }
 
   return NS_OK;
 }
 
-NS_IMETHODIMP
-nsWindowsShellService::GetCanSetDesktopBackground(bool* aResult)
-{
-  *aResult = true;
-  return NS_OK;
-}
-
 static nsresult
 DynSHOpenWithDialog(HWND hwndParent, const OPENASINFO *poainfo)
 {
   // shell32.dll is in the knownDLLs list so will always be loaded from the
   // system32 directory.
   static const wchar_t kSehllLibraryName[] =  L"shell32.dll";
   HMODULE shellDLL = ::LoadLibraryW(kSehllLibraryName);
   if (!shellDLL) {
@@ -979,49 +966,16 @@ nsWindowsShellService::SetDefaultBrowser
     // Reset the number of times the dialog should be shown
     // before it is silenced.
     (void) prefs->SetIntPref(PREF_DEFAULTBROWSERCHECKCOUNT, 0);
   }
 
   return rv;
 }
 
-NS_IMETHODIMP
-nsWindowsShellService::GetShouldCheckDefaultBrowser(bool* aResult)
-{
-  NS_ENSURE_ARG_POINTER(aResult);
-
-  // If we've already checked, the browser has been started and this is a
-  // new window open, and we don't want to check again.
-  if (mCheckedThisSession) {
-    *aResult = false;
-    return NS_OK;
-  }
-
-  nsresult rv;
-  nsCOMPtr<nsIPrefBranch> prefs(do_GetService(NS_PREFSERVICE_CONTRACTID, &rv));
-  if (NS_FAILED(rv)) {
-    return rv;
-  }
-
-  return prefs->GetBoolPref(PREF_CHECKDEFAULTBROWSER, aResult);
-}
-
-NS_IMETHODIMP
-nsWindowsShellService::SetShouldCheckDefaultBrowser(bool aShouldCheck)
-{
-  nsresult rv;
-  nsCOMPtr<nsIPrefBranch> prefs(do_GetService(NS_PREFSERVICE_CONTRACTID, &rv));
-  if (NS_FAILED(rv)) {
-    return rv;
-  }
-
-  return prefs->SetBoolPref(PREF_CHECKDEFAULTBROWSER, aShouldCheck);
-}
-
 static nsresult
 WriteBitmap(nsIFile* aFile, imgIContainer* aImage)
 {
   nsresult rv;
 
   RefPtr<SourceSurface> surface =
     aImage->GetFrame(imgIContainer::FRAME_FIRST,
                      imgIContainer::FLAG_SYNC_DECODE);
@@ -1353,18 +1307,17 @@ nsWindowsShellService::SetDesktopBackgro
 
   rv = regKey->WriteStringValue(NS_LITERAL_STRING("Background"),
                                 nsDependentString(rgb));
   NS_ENSURE_SUCCESS(rv, rv);
 
   return regKey->Close();
 }
 
-nsWindowsShellService::nsWindowsShellService() : 
-  mCheckedThisSession(false) 
+nsWindowsShellService::nsWindowsShellService()
 {
 }
 
 nsWindowsShellService::~nsWindowsShellService()
 {
 }
 
 NS_IMETHODIMP
--- a/browser/components/shell/nsWindowsShellService.h
+++ b/browser/components/shell/nsWindowsShellService.h
@@ -26,14 +26,11 @@ public:
   NS_DECL_NSIWINDOWSSHELLSERVICE
 
 protected:
   bool IsDefaultBrowserVista(bool aCheckAllTypes, bool* aIsDefaultBrowser);
   nsresult LaunchControlPanelDefaultsSelectionUI();
   nsresult LaunchModernSettingsDialogDefaultApps();
   nsresult InvokeHTTPOpenAsVerb();
   nsresult LaunchHTTPHandlerPane();
-
-private:
-  bool      mCheckedThisSession;
 };
 
 #endif // nswindowsshellservice_h____
--- a/browser/components/shell/test/browser_633221.js
+++ b/browser/components/shell/test/browser_633221.js
@@ -1,15 +1,7 @@
-function test() {
-  let osString = Cc["@mozilla.org/xre/app-info;1"].
-                 getService(Ci.nsIXULRuntime).OS;
-
-  // this test is Linux-specific
-  if (osString != "Linux")
-    return;
+Components.utils.import("resource:///modules/ShellService.jsm");
 
-  let shell = Cc["@mozilla.org/browser/shell-service;1"].
-              getService(Ci.nsIShellService);
-
-  shell.setDefaultBrowser(true, false);
-  ok(shell.isDefaultBrowser(true, false), "we got here and are the default browser");
-  ok(shell.isDefaultBrowser(true, true), "we got here and are the default browser");
+function test() {
+  ShellService.setDefaultBrowser(true, false);
+  ok(ShellService.isDefaultBrowser(true, false), "we got here and are the default browser");
+  ok(ShellService.isDefaultBrowser(true, true), "we got here and are the default browser");
 }
--- a/toolkit/components/telemetry/TelemetryEnvironment.jsm
+++ b/toolkit/components/telemetry/TelemetryEnvironment.jsm
@@ -1005,28 +1005,39 @@ EnvironmentCache.prototype = {
   /**
    * Determine if we're the default browser.
    * @returns null on error, true if we are the default browser, or false otherwise.
    */
   _isDefaultBrowser: function () {
     if (AppConstants.platform === "gonk") {
       return true;
     }
+
     if (!("@mozilla.org/browser/shell-service;1" in Cc)) {
       this._log.info("_isDefaultBrowser - Could not obtain browser shell service");
       return null;
     }
 
     let shellService;
     try {
-      shellService = Cc["@mozilla.org/browser/shell-service;1"]
-                       .getService(Ci.nsIShellService);
+      let scope = {};
+      Cu.import("resource:///modules/ShellService.jsm", scope);
+      shellService = scope.ShellService;
     } catch (ex) {
-      this._log.error("_isDefaultBrowser - Could not obtain shell service", ex);
-      return null;
+      this._log.error("_isDefaultBrowser - Could not obtain shell service JSM");
+    }
+
+    if (!shellService) {
+      try {
+        shellService = Cc["@mozilla.org/browser/shell-service;1"]
+                         .getService(Ci.nsIShellService);
+      } catch (ex) {
+        this._log.error("_isDefaultBrowser - Could not obtain shell service", ex);
+        return null;
+      }
     }
 
     try {
       // This uses the same set of flags used by the pref pane.
       return shellService.isDefaultBrowser(false, true) ? true : false;
     } catch (ex) {
       this._log.error("_isDefaultBrowser - Could not determine if default browser", ex);
       return null;