Bug 1230209 - Add more telemetry for Geolocation usage f=bsmedberg r=tanvi,rbarnes,jdm
authorTim Taubert <ttaubert@mozilla.com>
Thu, 03 Dec 2015 19:12:11 +0100
changeset 315232 e1ddfdbf048c
parent 315231 f6bd24864d7b
child 315233 64fd6e1c4fc1
push id5703
push userraliiev@mozilla.com
push dateMon, 07 Mar 2016 14:18:41 +0000
treeherdermozilla-beta@31e373ad5b5f [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerstanvi, rbarnes, jdm
bugs1230209
milestone46.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 1230209 - Add more telemetry for Geolocation usage f=bsmedberg r=tanvi,rbarnes,jdm
dom/geolocation/nsGeolocation.cpp
dom/geolocation/nsGeolocation.h
toolkit/components/telemetry/Histograms.json
--- a/dom/geolocation/nsGeolocation.cpp
+++ b/dom/geolocation/nsGeolocation.cpp
@@ -85,16 +85,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();
@@ -115,16 +116,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;
@@ -349,25 +351,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);
     }
   }
@@ -448,29 +452,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();
@@ -1188,17 +1204,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();
   }
@@ -1229,16 +1246,34 @@ Geolocation::Init(nsIDOMWindow* aContent
 
     if (XRE_IsContentProcess()) {
       doc->AddSystemEventListener(NS_LITERAL_STRING("visibilitychange"),
                                   /* listener */ this,
                                   /* use capture */ true,
                                   /* wants untrusted */ false);
     }
 
+    nsCOMPtr<nsIURI> uri;
+    nsresult rv = mPrincipal->GetURI(getter_AddRefs(uri));
+    NS_ENSURE_SUCCESS(rv, rv);
+
+    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);
@@ -1489,21 +1524,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()) {
@@ -1578,25 +1615,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
@@ -213,16 +213,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
@@ -439,16 +439,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",