Bug 1230209 - Add more telemetry for Geolocation usage f=bsmedberg r=tanvi,rbarnes,jdm a=sylvestre
authorTim Taubert <tim@timtaubert.de>
Thu, 21 Jan 2016 14:15:33 +0100
changeset 310912 882e6011c18f968f3e6993e4fac60c68ae6366a0
parent 310911 ec2bd9b72622961153d7f3c4b3fd01dcad5b0295
child 310913 b468f7200bc2978f7ed947de8d7c07bc03af015c
push id5513
push userraliiev@mozilla.com
push dateMon, 25 Jan 2016 13:55:34 +0000
treeherdermozilla-beta@5ee97dd05b5c [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerstanvi, rbarnes, jdm, sylvestre
bugs1230209
milestone45.0a2
Bug 1230209 - Add more telemetry for Geolocation usage f=bsmedberg r=tanvi,rbarnes,jdm a=sylvestre
dom/geolocation/nsGeolocation.cpp
dom/geolocation/nsGeolocation.h
toolkit/components/telemetry/Histograms.json
--- a/dom/geolocation/nsGeolocation.cpp
+++ b/dom/geolocation/nsGeolocation.cpp
@@ -79,16 +79,17 @@ class nsGeolocationRequest final
   NS_DECL_NSIGEOLOCATIONUPDATE
 
   NS_DECL_CYCLE_COLLECTION_CLASS_AMBIGUOUS(nsGeolocationRequest, nsIContentPermissionRequest)
 
   nsGeolocationRequest(Geolocation* aLocator,
                        const GeoPositionCallback& aCallback,
                        const GeoPositionErrorCallback& aErrorCallback,
                        PositionOptions* aOptions,
+                       uint8_t aProtocolType,
                        bool aWatchPositionRequest = false,
                        int32_t aWatchId = 0);
   void Shutdown();
 
   void SendLocation(nsIDOMGeoPosition* aLocation);
   bool WantsHighAccuracy() {return !mShutdown && mOptions && mOptions->mEnableHighAccuracy;}
   void SetTimeoutTimer();
   void StopTimeoutTimer();
@@ -109,16 +110,17 @@ class nsGeolocationRequest final
   GeoPositionErrorCallback mErrorCallback;
   nsAutoPtr<PositionOptions> mOptions;
 
   RefPtr<Geolocation> mLocator;
 
   int32_t mWatchId;
   bool mShutdown;
   nsCOMPtr<nsIContentPermissionRequester> mRequester;
+  uint8_t mProtocolType;
 };
 
 static PositionOptions*
 CreatePositionOptionsCopy(const PositionOptions& aOptions)
 {
   nsAutoPtr<PositionOptions> geoOptions(new PositionOptions());
 
   geoOptions->mEnableHighAccuracy = aOptions.mEnableHighAccuracy;
@@ -343,25 +345,27 @@ PositionError::NotifyCallback(const GeoP
 ////////////////////////////////////////////////////
 // nsGeolocationRequest
 ////////////////////////////////////////////////////
 
 nsGeolocationRequest::nsGeolocationRequest(Geolocation* aLocator,
                                            const GeoPositionCallback& aCallback,
                                            const GeoPositionErrorCallback& aErrorCallback,
                                            PositionOptions* aOptions,
+                                           uint8_t aProtocolType,
                                            bool aWatchPositionRequest,
                                            int32_t aWatchId)
   : mIsWatchPositionRequest(aWatchPositionRequest),
     mCallback(aCallback),
     mErrorCallback(aErrorCallback),
     mOptions(aOptions),
     mLocator(aLocator),
     mWatchId(aWatchId),
-    mShutdown(false)
+    mShutdown(false),
+    mProtocolType(aProtocolType)
 {
   nsCOMPtr<nsIDOMWindow> win = do_QueryReferent(mLocator->GetOwner());
   if (win) {
     nsCOMPtr<nsPIDOMWindow> window = do_QueryInterface(win);
     if (window) {
       mRequester = new nsContentPermissionRequester(window);
     }
   }
@@ -442,29 +446,41 @@ nsGeolocationRequest::GetElement(nsIDOME
   NS_ENSURE_ARG_POINTER(aRequestingElement);
   *aRequestingElement = nullptr;
   return NS_OK;
 }
 
 NS_IMETHODIMP
 nsGeolocationRequest::Cancel()
 {
+  if (mRequester) {
+    // Record the number of denied requests for regular web content.
+    // This method is only called when the user explicitly denies the request,
+    // and is not called when the page is simply unloaded, or similar.
+    Telemetry::Accumulate(Telemetry::GEOLOCATION_REQUEST_GRANTED, mProtocolType);
+  }
+
   if (mLocator->ClearPendingRequest(this)) {
     return NS_OK;
   }
 
   NotifyError(nsIDOMGeoPositionError::PERMISSION_DENIED);
   return NS_OK;
 }
 
 NS_IMETHODIMP
 nsGeolocationRequest::Allow(JS::HandleValue aChoices)
 {
   MOZ_ASSERT(aChoices.isUndefined());
 
+  if (mRequester) {
+    // Record the number of granted requests for regular web content.
+    Telemetry::Accumulate(Telemetry::GEOLOCATION_REQUEST_GRANTED, mProtocolType + 10);
+  }
+
   if (mLocator->ClearPendingRequest(this)) {
     return NS_OK;
   }
 
   RefPtr<nsGeolocationService> gs = nsGeolocationService::GetGeolocationService();
 
   bool canUseCache = false;
   CachedPositionAndAccuracy lastPosition = gs->GetCachedPosition();
@@ -1171,17 +1187,18 @@ NS_IMPL_CYCLE_COLLECTING_ADDREF(Geolocat
 NS_IMPL_CYCLE_COLLECTING_RELEASE(Geolocation)
 
 NS_IMPL_CYCLE_COLLECTION_WRAPPERCACHE(Geolocation,
                                       mPendingCallbacks,
                                       mWatchingCallbacks,
                                       mPendingRequests)
 
 Geolocation::Geolocation()
-: mLastWatchId(0)
+: mProtocolType(ProtocolType::OTHER)
+, mLastWatchId(0)
 {
 }
 
 Geolocation::~Geolocation()
 {
   if (mService) {
     Shutdown();
   }
@@ -1204,16 +1221,37 @@ Geolocation::Init(nsIDOMWindow* aContent
 
     // Grab the principal of the document
     nsCOMPtr<nsIDocument> doc = window->GetDoc();
     if (!doc) {
       return NS_ERROR_FAILURE;
     }
 
     mPrincipal = doc->NodePrincipal();
+
+    nsCOMPtr<nsIURI> uri;
+    nsresult rv = mPrincipal->GetURI(getter_AddRefs(uri));
+    NS_ENSURE_SUCCESS(rv, rv);
+
+    if (uri) {
+      bool isHttp;
+      rv = uri->SchemeIs("http", &isHttp);
+      NS_ENSURE_SUCCESS(rv, rv);
+
+      bool isHttps;
+      rv = uri->SchemeIs("https", &isHttps);
+      NS_ENSURE_SUCCESS(rv, rv);
+
+      // Store the protocol to send via telemetry later.
+      if (isHttp) {
+        mProtocolType = ProtocolType::HTTP;
+      } else if (isHttps) {
+        mProtocolType = ProtocolType::HTTPS;
+      }
+    }
   }
 
   // If no aContentDom was passed into us, we are being used
   // by chrome/c++ and have no mOwner, no mPrincipal, and no need
   // to prompt.
   mService = nsGeolocationService::GetGeolocationService();
   if (mService) {
     mService->AddLocator(this);
@@ -1400,21 +1438,23 @@ nsresult
 Geolocation::GetCurrentPosition(GeoPositionCallback& callback,
                                 GeoPositionErrorCallback& errorCallback,
                                 PositionOptions *options)
 {
   if (mPendingCallbacks.Length() > MAX_GEO_REQUESTS_PER_WINDOW) {
     return NS_ERROR_NOT_AVAILABLE;
   }
 
-  RefPtr<nsGeolocationRequest> request = new nsGeolocationRequest(this,
-                                                                    callback,
-                                                                    errorCallback,
-                                                                    options,
-                                                                    false);
+  // Count the number of requests per protocol/scheme.
+  Telemetry::Accumulate(Telemetry::GEOLOCATION_GETCURRENTPOSITION_SECURE_ORIGIN,
+                        static_cast<uint8_t>(mProtocolType));
+
+  RefPtr<nsGeolocationRequest> request =
+    new nsGeolocationRequest(this, callback, errorCallback, options,
+                             static_cast<uint8_t>(mProtocolType), false);
 
   if (!sGeoEnabled) {
     nsCOMPtr<nsIRunnable> ev = new RequestAllowEvent(false, request);
     NS_DispatchToMainThread(ev);
     return NS_OK;
   }
 
   if (!mOwner && !nsContentUtils::LegacyIsCallerChromeOrNativeCode()) {
@@ -1489,25 +1529,26 @@ Geolocation::WatchPosition(GeoPositionCa
                            GeoPositionErrorCallback& aErrorCallback,
                            PositionOptions* aOptions,
                            int32_t* aRv)
 {
   if (mWatchingCallbacks.Length() > MAX_GEO_REQUESTS_PER_WINDOW) {
     return NS_ERROR_NOT_AVAILABLE;
   }
 
+  // Count the number of requests per protocol/scheme.
+  Telemetry::Accumulate(Telemetry::GEOLOCATION_WATCHPOSITION_SECURE_ORIGIN,
+                        static_cast<uint8_t>(mProtocolType));
+
   // The watch ID:
   *aRv = mLastWatchId++;
 
-  RefPtr<nsGeolocationRequest> request = new nsGeolocationRequest(this,
-                                                                    aCallback,
-                                                                    aErrorCallback,
-                                                                    aOptions,
-                                                                    true,
-                                                                    *aRv);
+  RefPtr<nsGeolocationRequest> request =
+    new nsGeolocationRequest(this, aCallback, aErrorCallback, aOptions,
+                             static_cast<uint8_t>(mProtocolType), true, *aRv);
 
   if (!sGeoEnabled) {
     GPSLOG("request allow event");
     nsCOMPtr<nsIRunnable> ev = new RequestAllowEvent(false, request);
     NS_DispatchToMainThread(ev);
     return NS_OK;
   }
 
--- a/dom/geolocation/nsGeolocation.h
+++ b/dom/geolocation/nsGeolocation.h
@@ -205,16 +205,22 @@ private:
   nsTArray<RefPtr<nsGeolocationRequest> > mWatchingCallbacks;
 
   // window that this was created for.  Weak reference.
   nsWeakPtr mOwner;
 
   // where the content was loaded from
   nsCOMPtr<nsIPrincipal> mPrincipal;
 
+  // the protocols we want to measure
+  enum class ProtocolType: uint8_t { OTHER, HTTP, HTTPS };
+
+  // the protocol used to load the content
+  ProtocolType mProtocolType;
+
   // owning back pointer.
   RefPtr<nsGeolocationService> mService;
 
   // Watch ID
   uint32_t mLastWatchId;
 
   // Pending requests are used when the service is not ready
   nsTArray<RefPtr<nsGeolocationRequest> > mPendingRequests;
--- a/toolkit/components/telemetry/Histograms.json
+++ b/toolkit/components/telemetry/Histograms.json
@@ -440,16 +440,37 @@
     "n_buckets": 50,
     "description": "Location accuracy"
   },
   "GEOLOCATION_ERROR": {
     "expires_in_version": "never",
     "kind": "flag",
     "description": "Has seen location error"
   },
+  "GEOLOCATION_GETCURRENTPOSITION_SECURE_ORIGIN" : {
+    "expires_in_version" : "55",
+    "kind": "enumerated",
+    "n_values": 10,
+    "bug_numbers": [1230209],
+    "description" : "Number of navigator.geolocation.getCurrentPosition() calls (0=other, 1=http, 2=https)"
+  },
+  "GEOLOCATION_REQUEST_GRANTED": {
+    "expires_in_version": "55",
+    "kind": "enumerated",
+    "n_values": 20,
+    "bug_numbers": [1230209],
+    "description": "Geolocation requests either granted or denied (0=denied/other, 1=denied/http, 2=denied/https, ..., 10=granted/other, 11=granted/http, 12=granted/https)"
+  },
+  "GEOLOCATION_WATCHPOSITION_SECURE_ORIGIN" : {
+    "expires_in_version" : "55",
+    "kind": "enumerated",
+    "n_values": 10,
+    "bug_numbers": [1230209],
+    "description" : "Number of navigator.geolocation.watchPosition() calls (0=other, 1=http, 2=https)"
+  },
   "GEOLOCATION_WIN8_SOURCE_IS_MLS": {
     "expires_in_version": "default",
     "kind": "boolean",
     "description": "Geolocation on Win8 is either MLS or native"
   },
   "GEOLOCATION_OSX_SOURCE_IS_MLS": {
     "expires_in_version": "default",
     "kind": "boolean",