Bug 1529591 - Check Mac system geo permission prior to showing request permission dialog. r=jdm
☠☠ backed out by ef6f20c81db1 ☠ ☠
authorGarvan Keeley <garvankeeley@gmail.com>
Thu, 04 Jul 2019 18:34:31 +0000
changeset 481318 14faf5e9443e08f1c9ca8a010c7e4214783116a9
parent 481317 e5c6fb94a7eba27d4928e56b388207fd7c60ba18
child 481319 93b614e367acb0a08bdea00093e9a0c4022c4c0f
push id36239
push useropoprus@mozilla.com
push dateFri, 05 Jul 2019 06:46:18 +0000
treeherdermozilla-central@b7030ce607ec [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersjdm
bugs1529591
milestone69.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 1529591 - Check Mac system geo permission prior to showing request permission dialog. r=jdm Differential Revision: https://phabricator.services.mozilla.com/D36030
dom/geolocation/nsGeolocation.cpp
dom/geolocation/nsGeolocation.h
dom/ipc/ContentParent.cpp
dom/ipc/ContentParent.h
dom/ipc/PContent.ipdl
dom/system/mac/CoreLocationLocationProvider.h
dom/system/mac/CoreLocationLocationProvider.mm
dom/system/mac/moz.build
--- a/dom/geolocation/nsGeolocation.cpp
+++ b/dom/geolocation/nsGeolocation.cpp
@@ -1223,31 +1223,61 @@ bool Geolocation::WindowOwnerStillExists
 void Geolocation::NotifyAllowedRequest(nsGeolocationRequest* aRequest) {
   if (aRequest->IsWatch()) {
     mWatchingCallbacks.AppendElement(aRequest);
   } else {
     mPendingCallbacks.AppendElement(aRequest);
   }
 }
 
-bool Geolocation::RegisterRequestWithPrompt(nsGeolocationRequest* request) {
+bool Geolocation::RegisterRequestWithPromptImpl(
+    nsGeolocationRequest* aRequest) {
   nsIEventTarget* target = MainThreadTarget(this);
-  ContentPermissionRequestBase::PromptResult pr = request->CheckPromptPrefs();
+  ContentPermissionRequestBase::PromptResult pr = aRequest->CheckPromptPrefs();
   if (pr == ContentPermissionRequestBase::PromptResult::Granted) {
-    request->RequestDelayedTask(target,
-                                nsGeolocationRequest::DelayedTaskType::Allow);
+    aRequest->RequestDelayedTask(target,
+                                 nsGeolocationRequest::DelayedTaskType::Allow);
     return true;
   }
   if (pr == ContentPermissionRequestBase::PromptResult::Denied) {
-    request->RequestDelayedTask(target,
-                                nsGeolocationRequest::DelayedTaskType::Deny);
+    aRequest->RequestDelayedTask(target,
+                                 nsGeolocationRequest::DelayedTaskType::Deny);
     return true;
   }
 
-  request->RequestDelayedTask(target,
-                              nsGeolocationRequest::DelayedTaskType::Request);
+  aRequest->RequestDelayedTask(target,
+                               nsGeolocationRequest::DelayedTaskType::Request);
   return true;
 }
 
+bool Geolocation::RegisterRequestWithPrompt(nsGeolocationRequest* request) {
+#ifdef MOZ_WIDGET_COCOA
+  RefPtr<Geolocation> self = this;
+  RefPtr<nsGeolocationRequest> req = request;
+  nsCOMPtr<nsISerialEventTarget> serialTarget =
+      SystemGroup::EventTargetFor(TaskCategory::Other);
+  ContentChild* cpc = ContentChild::GetSingleton();
+  cpc->SendGetGeoSysPermission()->Then(
+      serialTarget, __func__,
+      [req, self](bool aSysPermIsGranted) {
+        if (!aSysPermIsGranted) {
+          nsIEventTarget* target = MainThreadTarget(self);
+          req->RequestDelayedTask(
+              target, nsGeolocationRequest::DelayedTaskType::Deny);
+        } else {
+          self->RegisterRequestWithPromptImpl(req);
+        }
+      },
+      [req, self](mozilla::ipc::ResponseRejectReason aReason) {
+        nsIEventTarget* target = MainThreadTarget(self);
+        req->RequestDelayedTask(
+            target, nsGeolocationRequest::DelayedTaskType::Deny);
+      });
+  return true;
+#else
+  return RegisterRequestWithPromptImpl(request);
+#endif
+}
+
 JSObject* Geolocation::WrapObject(JSContext* aCtx,
                                   JS::Handle<JSObject*> aGivenProto) {
   return Geolocation_Binding::Wrap(aCtx, this, aGivenProto);
 }
--- a/dom/geolocation/nsGeolocation.h
+++ b/dom/geolocation/nsGeolocation.h
@@ -192,16 +192,18 @@ class Geolocation final : public nsIGeol
   MOZ_CAN_RUN_SCRIPT
   int32_t WatchPosition(GeoPositionCallback aCallback,
                         GeoPositionErrorCallback aErrorCallback,
                         UniquePtr<PositionOptions>&& aOptions,
                         CallerType aCallerType, ErrorResult& aRv);
 
   bool RegisterRequestWithPrompt(nsGeolocationRequest* request);
 
+  bool RegisterRequestWithPromptImpl(nsGeolocationRequest* aRequest);
+
   // Check if clearWatch is already called
   bool IsAlreadyCleared(nsGeolocationRequest* aRequest);
 
   // Returns whether the Geolocation object should block requests
   // within a context that is not secure.
   bool ShouldBlockInsecureRequests() const;
 
   // Return whather the Feature 'geolocation' is blocked by FeaturePolicy
--- a/dom/ipc/ContentParent.cpp
+++ b/dom/ipc/ContentParent.cpp
@@ -229,16 +229,17 @@
 #include "mozilla/Sprintf.h"
 
 #ifdef MOZ_WEBRTC
 #  include "signaling/src/peerconnection/WebrtcGlobalParent.h"
 #endif
 
 #if defined(XP_MACOSX)
 #  include "nsMacUtilsImpl.h"
+#  include "CoreLocationLocationProvider.h"
 #endif
 
 #if defined(ANDROID) || defined(LINUX)
 #  include "nsSystemInfo.h"
 #endif
 
 #if defined(XP_LINUX)
 #  include "mozilla/Hal.h"
@@ -4024,16 +4025,24 @@ mozilla::ipc::IPCResult ContentParent::R
     const IPC::Principal& aPrincipal, const bool& aHighAccuracy) {
   // To ensure no geolocation updates are skipped, we always force the
   // creation of a new listener.
   RecvRemoveGeolocationListener();
   mGeolocationWatchID = AddGeolocationListener(this, this, aHighAccuracy);
   return IPC_OK();
 }
 
+mozilla::ipc::IPCResult ContentParent::RecvGetGeoSysPermission(
+    std::function<void(const bool)>&& aCallback) {
+#ifdef MOZ_WIDGET_COCOA
+  aCallback(isMacGeoSystemPermissionEnabled());
+#endif
+  return IPC_OK();
+}
+
 mozilla::ipc::IPCResult ContentParent::RecvRemoveGeolocationListener() {
   if (mGeolocationWatchID != -1) {
     RefPtr<Geolocation> geo = Geolocation::NonWindowSingleton();
     geo->ClearWatch(mGeolocationWatchID);
     mGeolocationWatchID = -1;
   }
   return IPC_OK();
 }
--- a/dom/ipc/ContentParent.h
+++ b/dom/ipc/ContentParent.h
@@ -1010,16 +1010,19 @@ class ContentParent final : public PCont
 
   // MOZ_CAN_RUN_SCRIPT_BOUNDARY because we don't have MOZ_CAN_RUN_SCRIPT bits
   // in IPC code yet.
   MOZ_CAN_RUN_SCRIPT_BOUNDARY
   mozilla::ipc::IPCResult RecvAddGeolocationListener(
       const IPC::Principal& aPrincipal, const bool& aHighAccuracy);
   mozilla::ipc::IPCResult RecvRemoveGeolocationListener();
 
+  mozilla::ipc::IPCResult RecvGetGeoSysPermission(
+      std::function<void(const bool)>&& aCallback);
+
   // MOZ_CAN_RUN_SCRIPT_BOUNDARY because we don't have MOZ_CAN_RUN_SCRIPT bits
   // in IPC code yet.
   MOZ_CAN_RUN_SCRIPT_BOUNDARY
   mozilla::ipc::IPCResult RecvSetGeolocationHigherAccuracy(const bool& aEnable);
 
   mozilla::ipc::IPCResult RecvConsoleMessage(const nsString& aMessage);
 
   mozilla::ipc::IPCResult RecvScriptError(
--- a/dom/ipc/PContent.ipdl
+++ b/dom/ipc/PContent.ipdl
@@ -946,16 +946,18 @@ parent:
                              nullable PBrowser aBrowser);
 
     async PHandlerService();
 
     async AddGeolocationListener(Principal principal, bool highAccuracy);
     async RemoveGeolocationListener();
     async SetGeolocationHigherAccuracy(bool enable);
 
+   async GetGeoSysPermission() returns (bool isok);
+
     async ConsoleMessage(nsString message);
     async ScriptError(nsString message, nsString sourceName, nsString sourceLine,
                       uint32_t lineNumber, uint32_t colNumber, uint32_t flags,
                       nsCString category, bool privateWindow,
                       bool fromChromeContext);
     async ScriptErrorWithStack(nsString message, nsString sourceName, nsString sourceLine,
                                uint32_t lineNumber, uint32_t colNumber, uint32_t flags,
                                nsCString category, bool privateWindow,
--- a/dom/system/mac/CoreLocationLocationProvider.h
+++ b/dom/system/mac/CoreLocationLocationProvider.h
@@ -20,16 +20,18 @@
  * The solution then is to forward-declare CoreLocationObjects here and
  * hold a pointer to it in CoreLocationLocationProvider, and only actually
  * define it in CoreLocationLocationProvider.mm, thus making it safe
  * for nsGeolocation.cpp, which is C++-only, to include this header.
  */
 class CoreLocationObjects;
 class MLSFallback;
 
+bool isMacGeoSystemPermissionEnabled();
+
 class CoreLocationLocationProvider : public nsIGeolocationProvider {
  public:
   NS_DECL_ISUPPORTS
   NS_DECL_NSIGEOLOCATIONPROVIDER
 
   CoreLocationLocationProvider();
   // MOZ_CAN_RUN_SCRIPT_BOUNDARY because we can't mark Objective-C methods as
   // MOZ_CAN_RUN_SCRIPT as far as I can tell, and this method is called from
--- a/dom/system/mac/CoreLocationLocationProvider.mm
+++ b/dom/system/mac/CoreLocationLocationProvider.mm
@@ -27,16 +27,18 @@
 
 #include "nsObjCExceptions.h"
 
 using namespace mozilla;
 
 static const CLLocationAccuracy kHIGH_ACCURACY = kCLLocationAccuracyBest;
 static const CLLocationAccuracy kDEFAULT_ACCURACY = kCLLocationAccuracyNearestTenMeters;
 
+bool isMacGeoSystemPermissionEnabled() { return [CLLocationManager locationServicesEnabled]; }
+
 @interface LocationDelegate : NSObject <CLLocationManagerDelegate> {
   CoreLocationLocationProvider* mProvider;
 }
 
 - (id)init:(CoreLocationLocationProvider*)aProvider;
 - (void)locationManager:(CLLocationManager*)aManager didFailWithError:(NSError*)aError;
 - (void)locationManager:(CLLocationManager*)aManager didUpdateLocations:(NSArray*)locations;
 
--- a/dom/system/mac/moz.build
+++ b/dom/system/mac/moz.build
@@ -5,16 +5,17 @@
 # file, You can obtain one at http://mozilla.org/MPL/2.0/.
 
 SOURCES += [
     'CoreLocationLocationProvider.mm',
     'nsOSPermissionRequest.mm',
 ]
 
 EXPORTS += [
+    'CoreLocationLocationProvider.h',
     'nsOSPermissionRequest.h',
 ]
 
 include('/ipc/chromium/chromium-config.mozbuild')
 
 FINAL_LIBRARY = 'xul'
 LOCAL_INCLUDES += [
     '/dom/geolocation',