MLSFallback.cpp (3412B)
1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ 2 /* vim: set ts=8 sts=2 et sw=2 tw=80: */ 3 /* This Source Code Form is subject to the terms of the Mozilla Public 4 * License, v. 2.0. If a copy of the MPL was not distributed with this 5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 6 7 #include "MLSFallback.h" 8 9 #include "GeolocationPosition.h" 10 #include "mozilla/Logging.h" 11 #include "mozilla/glean/DomGeolocationMetrics.h" 12 #include "nsComponentManagerUtils.h" 13 #include "nsIGeolocationProvider.h" 14 #include "nsServiceManagerUtils.h" 15 16 extern mozilla::LazyLogModule gGeolocationLog; 17 18 NS_IMPL_ISUPPORTS(MLSFallback, nsITimerCallback, nsINamed) 19 20 MLSFallback::MLSFallback(uint32_t delay) : mDelayMs(delay) {} 21 22 MLSFallback::~MLSFallback() = default; 23 24 mozilla::glean::geolocation::FallbackLabel MapReasonToLabel( 25 MLSFallback::FallbackReason aReason) { 26 switch (aReason) { 27 case MLSFallback::FallbackReason::Error: 28 return mozilla::glean::geolocation::FallbackLabel::eOnError; 29 case MLSFallback::FallbackReason::Timeout: 30 return mozilla::glean::geolocation::FallbackLabel::eOnTimeout; 31 default: 32 MOZ_CRASH("Unexpected fallback reason"); 33 return mozilla::glean::geolocation::FallbackLabel::eOnError; 34 } 35 } 36 37 nsresult MLSFallback::Startup(nsIGeolocationUpdate* aWatcher, 38 FallbackReason aReason) { 39 if (mHandoffTimer || mMLSFallbackProvider) { 40 return NS_OK; 41 } 42 43 mUpdateWatcher = aWatcher; 44 45 // No need to schedule a timer callback if there is no startup delay. 46 if (mDelayMs == 0) { 47 mozilla::glean::geolocation::fallback.EnumGet(MapReasonToLabel(aReason)) 48 .Add(); 49 return CreateMLSFallbackProvider(); 50 } 51 52 return NS_NewTimerWithCallback(getter_AddRefs(mHandoffTimer), this, mDelayMs, 53 nsITimer::TYPE_ONE_SHOT); 54 } 55 56 nsresult MLSFallback::Shutdown(ShutdownReason aReason) { 57 if (aReason == ShutdownReason::ProviderResponded) { 58 mozilla::glean::geolocation::fallback 59 .EnumGet(mozilla::glean::geolocation::FallbackLabel::eNone) 60 .Add(); 61 } 62 63 mUpdateWatcher = nullptr; 64 65 if (mHandoffTimer) { 66 mHandoffTimer->Cancel(); 67 mHandoffTimer = nullptr; 68 } 69 70 nsresult rv = NS_OK; 71 if (mMLSFallbackProvider) { 72 rv = mMLSFallbackProvider->Shutdown(); 73 mMLSFallbackProvider = nullptr; 74 } 75 return rv; 76 } 77 78 NS_IMETHODIMP 79 MLSFallback::Notify(nsITimer* aTimer) { 80 mozilla::glean::geolocation::fallback 81 .EnumGet(mozilla::glean::geolocation::FallbackLabel::eOnTimeout) 82 .Add(); 83 return CreateMLSFallbackProvider(); 84 } 85 86 NS_IMETHODIMP 87 MLSFallback::GetName(nsACString& aName) { 88 aName.AssignLiteral("MLSFallback"); 89 return NS_OK; 90 } 91 92 nsresult MLSFallback::CreateMLSFallbackProvider() { 93 if (mMLSFallbackProvider || !mUpdateWatcher) { 94 return NS_OK; 95 } 96 97 MOZ_LOG(gGeolocationLog, mozilla::LogLevel::Debug, 98 ("Falling back to NetworkLocationProvider")); 99 100 nsresult rv; 101 mMLSFallbackProvider = 102 do_CreateInstance("@mozilla.org/geolocation/mls-provider;1", &rv); 103 NS_ENSURE_SUCCESS(rv, rv); 104 105 if (mMLSFallbackProvider) { 106 rv = mMLSFallbackProvider->Startup(); 107 if (NS_SUCCEEDED(rv)) { 108 MOZ_LOG(gGeolocationLog, mozilla::LogLevel::Debug, 109 ("Successfully started up NetworkLocationProvider")); 110 mMLSFallbackProvider->Watch(mUpdateWatcher); 111 } 112 } 113 mUpdateWatcher = nullptr; 114 return rv; 115 }