Bug 707659 - Part 1: DOM implementation, r=jlebar
authorVicamo Yang <vyang@mozilla.com>
Thu, 23 Aug 2012 01:30:27 +0800
changeset 103031 b87b0846c9137de02fdf9a0e8e1db19231cf3098
parent 103030 e97800e74b636eb088edd68ee219a8a30c7dc9b3
child 103032 c5ca56e666683e5c96a1c89fc9e3d420200a9637
push id13784
push uservyang@mozilla.com
push dateWed, 22 Aug 2012 17:31:05 +0000
treeherdermozilla-inbound@c5ca56e66668 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersjlebar
bugs707659
milestone17.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 707659 - Part 1: DOM implementation, r=jlebar
dom/base/Navigator.cpp
dom/base/Navigator.h
dom/sms/src/SmsManager.cpp
dom/sms/src/SmsManager.h
modules/libpref/src/init/all.js
--- a/dom/base/Navigator.cpp
+++ b/dom/base/Navigator.cpp
@@ -51,16 +51,17 @@
 #include "BluetoothManager.h"
 #endif
 #include "nsIDOMCameraManager.h"
 #include "DOMCameraManager.h"
 
 #include "nsIDOMGlobalPropertyInitializer.h"
 
 using namespace mozilla::dom::power;
+using namespace mozilla::dom::sms;
 
 // This should not be in the namespace.
 DOMCI_DATA(Navigator, mozilla::dom::Navigator)
 
 namespace mozilla {
 namespace dom {
 
 static const char sJSStackContractID[] = "@mozilla.org/js/xpc/ContextStack;1";
@@ -1060,71 +1061,16 @@ Navigator::RequestWakeLock(const nsAStri
   return pmService->NewWakeLock(aTopic, win, aWakeLock);
 }
 
 //*****************************************************************************
 //    Navigator::nsIDOMNavigatorSms
 //*****************************************************************************
 
 bool
-Navigator::IsSmsAllowed() const
-{
-  static const bool defaultSmsPermission = false;
-
-  // First of all, the general pref has to be turned on.
-  if (!Preferences::GetBool("dom.sms.enabled", defaultSmsPermission)) {
-    return false;
-  }
-
-  // In addition of having 'dom.sms.enabled' set to true, we require the
-  // website to be whitelisted. This is a temporary 'security model'.
-  // 'dom.sms.whitelist' has to contain comma-separated values of URI prepath.
-  // For local files, "file://" must be listed.
-  // For data-urls: "moz-nullprincipal:".
-  // Chrome files also have to be whitelisted for the moment.
-  nsCOMPtr<nsPIDOMWindow> win(do_QueryReferent(mWindow));
-
-  if (!win || !win->GetDocShell()) {
-    return defaultSmsPermission;
-  }
-
-  nsCOMPtr<nsIDocument> doc = do_QueryInterface(win->GetExtantDocument());
-  if (!doc) {
-    return defaultSmsPermission;
-  }
-
-  nsCOMPtr<nsIURI> uri;
-  doc->NodePrincipal()->GetURI(getter_AddRefs(uri));
-
-  if (!uri) {
-    return defaultSmsPermission;
-  }
-
-  nsCAutoString uriPrePath;
-  uri->GetPrePath(uriPrePath);
-
-  const nsAdoptingString& whitelist =
-    Preferences::GetString("dom.sms.whitelist");
-
-  nsCharSeparatedTokenizer tokenizer(whitelist, ',',
-                                     nsCharSeparatedTokenizerTemplate<>::SEPARATOR_OPTIONAL);
-
-  while (tokenizer.hasMoreTokens()) {
-    const nsSubstring& whitelistItem = tokenizer.nextToken();
-
-    if (NS_ConvertUTF16toUTF8(whitelistItem).Equals(uriPrePath)) {
-      return true;
-    }
-  }
-
-  // The current page hasn't been whitelisted.
-  return false;
-}
-
-bool
 Navigator::IsSmsSupported() const
 {
 #ifdef MOZ_WEBSMS_BACKEND
   nsCOMPtr<nsISmsService> smsService = do_GetService(SMS_SERVICE_CONTRACTID);
   NS_ENSURE_TRUE(smsService, false);
 
   bool result = false;
   smsService->HasSupport(&result);
@@ -1136,25 +1082,25 @@ Navigator::IsSmsSupported() const
 }
 
 NS_IMETHODIMP
 Navigator::GetMozSms(nsIDOMMozSmsManager** aSmsManager)
 {
   *aSmsManager = nullptr;
 
   if (!mSmsManager) {
-    if (!IsSmsSupported() || !IsSmsAllowed()) {
+    if (!IsSmsSupported()) {
       return NS_OK;
     }
 
     nsCOMPtr<nsPIDOMWindow> window = do_QueryReferent(mWindow);
     NS_ENSURE_TRUE(window && window->GetDocShell(), NS_OK);
 
-    mSmsManager = new sms::SmsManager();
-    mSmsManager->Init(window);
+    mSmsManager = SmsManager::CheckPermissionAndCreateInstance(window);
+    NS_ENSURE_TRUE(mSmsManager, NS_OK);
   }
 
   NS_ADDREF(*aSmsManager = mSmsManager);
 
   return NS_OK;
 }
 
 #ifdef MOZ_B2G_RIL
--- a/dom/base/Navigator.h
+++ b/dom/base/Navigator.h
@@ -137,17 +137,16 @@ public:
 
 #ifdef MOZ_SYS_MSG
   // Helper to initialize mMessagesManager.
   nsresult EnsureMessagesManager();
 #endif
   NS_DECL_NSIDOMNAVIGATORCAMERA
 
 private:
-  bool IsSmsAllowed() const;
   bool IsSmsSupported() const;
 
   nsRefPtr<nsMimeTypeArray> mMimeTypes;
   nsRefPtr<nsPluginArray> mPlugins;
   nsRefPtr<nsGeolocation> mGeolocation;
   nsRefPtr<nsDesktopNotificationCenter> mNotification;
   nsRefPtr<battery::BatteryManager> mBatteryManager;
   nsRefPtr<power::PowerManager> mPowerManager;
--- a/dom/sms/src/SmsManager.cpp
+++ b/dom/sms/src/SmsManager.cpp
@@ -3,26 +3,28 @@
  * 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 "SmsFilter.h"
 #include "SmsManager.h"
 #include "nsIDOMClassInfo.h"
 #include "nsISmsService.h"
 #include "nsIObserverService.h"
+#include "mozilla/Preferences.h"
 #include "mozilla/Services.h"
 #include "Constants.h"
 #include "SmsEvent.h"
 #include "nsIDOMSmsMessage.h"
 #include "nsIDOMSmsRequest.h"
 #include "SmsRequestManager.h"
 #include "nsJSUtils.h"
 #include "nsContentUtils.h"
 #include "nsISmsDatabaseService.h"
 #include "nsIXPConnect.h"
+#include "nsIPermissionManager.h"
 
 /**
  * We have to use macros here because our leak analysis tool things we are
  * leaking strings when we have |static const nsString|. Sad :(
  */
 #define RECEIVED_EVENT_NAME  NS_LITERAL_STRING("received")
 #define SENT_EVENT_NAME      NS_LITERAL_STRING("sent")
 #define DELIVERED_EVENT_NAME NS_LITERAL_STRING("delivered")
@@ -54,16 +56,55 @@ NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION_
   NS_INTERFACE_MAP_ENTRY(nsIObserver)
   NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIDOMMozSmsManager)
   NS_DOM_INTERFACE_MAP_ENTRY_CLASSINFO(MozSmsManager)
 NS_INTERFACE_MAP_END_INHERITING(nsDOMEventTargetHelper)
 
 NS_IMPL_ADDREF_INHERITED(SmsManager, nsDOMEventTargetHelper)
 NS_IMPL_RELEASE_INHERITED(SmsManager, nsDOMEventTargetHelper)
 
+/* static */already_AddRefed<SmsManager>
+SmsManager::CheckPermissionAndCreateInstance(nsPIDOMWindow* aWindow)
+{
+  NS_ASSERTION(aWindow, "Null pointer!");
+
+  // First of all, the general pref has to be turned on.
+  bool enabled = false;
+  Preferences::GetBool("dom.sms.enabled", &enabled);
+  NS_ENSURE_TRUE(enabled, nullptr);
+
+  nsPIDOMWindow* innerWindow = aWindow->IsInnerWindow() ?
+    aWindow :
+    aWindow->GetCurrentInnerWindow();
+
+  // Need the document for security check.
+  nsCOMPtr<nsIDocument> document =
+    do_QueryInterface(innerWindow->GetExtantDocument());
+  NS_ENSURE_TRUE(document, nullptr);
+
+  nsCOMPtr<nsIPrincipal> principal = document->NodePrincipal();
+  NS_ENSURE_TRUE(principal, nullptr);
+
+  nsCOMPtr<nsIPermissionManager> permMgr =
+    do_GetService(NS_PERMISSIONMANAGER_CONTRACTID);
+  NS_ENSURE_TRUE(permMgr, nullptr);
+
+  PRUint32 permission = nsIPermissionManager::DENY_ACTION;
+  permMgr->TestPermissionFromPrincipal(principal, "sms", &permission);
+
+  if (permission != nsIPermissionManager::ALLOW_ACTION) {
+    return nullptr;
+  }
+
+  nsRefPtr<SmsManager> smsMgr = new SmsManager();
+  smsMgr->Init(aWindow);
+
+  return smsMgr.forget();
+}
+
 void
 SmsManager::Init(nsPIDOMWindow *aWindow)
 {
   BindToOwner(aWindow);
 
   nsCOMPtr<nsIObserverService> obs = services::GetObserverService();
   // GetObserverService() can return null is some situations like shutdown.
   if (!obs) {
--- a/dom/sms/src/SmsManager.h
+++ b/dom/sms/src/SmsManager.h
@@ -25,16 +25,19 @@ public:
   NS_DECL_NSIOBSERVER
   NS_DECL_NSIDOMMOZSMSMANAGER
 
   NS_FORWARD_NSIDOMEVENTTARGET(nsDOMEventTargetHelper::)
 
   NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED(SmsManager,
                                            nsDOMEventTargetHelper)
 
+  static already_AddRefed<SmsManager>
+  CheckPermissionAndCreateInstance(nsPIDOMWindow *aWindow);
+
   void Init(nsPIDOMWindow *aWindow);
   void Shutdown();
 
 private:
   /**
    * Internal Send() method used to send one message.
    */
   nsresult Send(JSContext* aCx, JSObject* aGlobal, JSString* aNumber,
--- a/modules/libpref/src/init/all.js
+++ b/modules/libpref/src/init/all.js
@@ -3630,17 +3630,16 @@ pref("dom.vibrator.enabled", true);
 pref("dom.vibrator.max_vibrate_ms", 10000);
 pref("dom.vibrator.max_vibrate_list_len", 128);
 
 // Battery API
 pref("dom.battery.enabled", true);
 
 // WebSMS
 pref("dom.sms.enabled", false);
-pref("dom.sms.whitelist", "");
 
 // WebContacts
 pref("dom.mozContacts.enabled", false);
 
 // WebAlarms
 pref("dom.mozAlarms.enabled", false);
 
 // WebSettings