[tor-commits] [tor-browser] 150/311: Bug 1757147 - make FetchService observe the network status. r=dom-worker-reviewers, asuth, jesup, a=dmeehan

gitolite role git at cupani.torproject.org
Tue Apr 26 15:29:10 UTC 2022


This is an automated email from the git hooks/post-receive script.

pierov pushed a commit to branch geckoview-99.0.1-11.0-1
in repository tor-browser.

commit 4387a6cb8e1dc248048b9e0f30169c9d290010e6
Author: Eden Chuang <echuang at mozilla.com>
AuthorDate: Mon Mar 14 15:31:22 2022 +0000

    Bug 1757147 - make FetchService observe the network status. r=dom-worker-reviewers,asuth,jesup, a=dmeehan
    
    Differential Revision: https://phabricator.services.mozilla.com/D139953
---
 dom/fetch/FetchService.cpp | 105 ++++++++++++++++++++++++++++++++++++++++++---
 dom/fetch/FetchService.h   |  11 ++++-
 2 files changed, 108 insertions(+), 8 deletions(-)

diff --git a/dom/fetch/FetchService.cpp b/dom/fetch/FetchService.cpp
index e951d1c498036..7fb3beaa0a1b0 100644
--- a/dom/fetch/FetchService.cpp
+++ b/dom/fetch/FetchService.cpp
@@ -2,14 +2,16 @@
  * 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 "nsContentUtils.h"
 #include "FetchLog.h"
+#include "nsContentUtils.h"
+#include "nsICookieJarSettings.h"
 #include "nsILoadGroup.h"
 #include "nsILoadInfo.h"
+#include "nsIIOService.h"
+#include "nsIObserverService.h"
 #include "nsIPrincipal.h"
-#include "nsICookieJarSettings.h"
-#include "nsNetUtil.h"
 #include "nsIScriptSecurityManager.h"
+#include "nsNetUtil.h"
 #include "nsThreadUtils.h"
 #include "nsXULAppAPI.h"
 #include "mozilla/BasePrincipal.h"
@@ -212,6 +214,8 @@ void FetchService::FetchInstance::FlushConsoleReport() {}
 
 // FetchService
 
+NS_IMPL_ISUPPORTS(FetchService, nsIObserver)
+
 StaticRefPtr<FetchService> gInstance;
 
 /*static*/
@@ -221,6 +225,11 @@ already_AddRefed<FetchService> FetchService::GetInstance() {
 
   if (!gInstance) {
     gInstance = MakeRefPtr<FetchService>();
+    nsresult rv = gInstance->RegisterNetworkObserver();
+    if (NS_WARN_IF(NS_FAILED(rv))) {
+      gInstance = nullptr;
+      return nullptr;
+    }
     ClearOnShutdown(&gInstance);
   }
   RefPtr<FetchService> service = gInstance;
@@ -239,15 +248,96 @@ FetchService::FetchService() {
   MOZ_ASSERT(NS_IsMainThread());
 }
 
-FetchService::~FetchService() = default;
+FetchService::~FetchService() {
+  MOZ_ALWAYS_SUCCEEDS(UnregisterNetworkObserver());
+}
+
+nsresult FetchService::RegisterNetworkObserver() {
+  AssertIsOnMainThread();
+  nsCOMPtr<nsIObserverService> observerService = services::GetObserverService();
+  if (!observerService) {
+    return NS_ERROR_UNEXPECTED;
+  }
+
+  nsCOMPtr<nsIIOService> ioService = services::GetIOService();
+  if (!ioService) {
+    return NS_ERROR_UNEXPECTED;
+  }
+
+  nsresult rv = observerService->AddObserver(
+      this, NS_IOSERVICE_OFFLINE_STATUS_TOPIC, false);
+  NS_ENSURE_SUCCESS(rv, rv);
+
+  rv = observerService->AddObserver(this, "xpcom-shutdown", false);
+  NS_ENSURE_SUCCESS(rv, rv);
+
+  rv = ioService->GetOffline(&mOffline);
+  NS_ENSURE_SUCCESS(rv, rv);
+  mObservingNetwork = true;
+
+  return NS_OK;
+}
+
+nsresult FetchService::UnregisterNetworkObserver() {
+  AssertIsOnMainThread();
+  nsresult rv;
+  if (mObservingNetwork) {
+    nsCOMPtr<nsIObserverService> observerService =
+        mozilla::services::GetObserverService();
+    if (observerService) {
+      rv = observerService->RemoveObserver(this,
+                                           NS_IOSERVICE_OFFLINE_STATUS_TOPIC);
+      NS_ENSURE_SUCCESS(rv, rv);
+      rv = observerService->RemoveObserver(this, "xpcom-shutdown");
+      NS_ENSURE_SUCCESS(rv, rv);
+    }
+    mObservingNetwork = false;
+  }
+  return NS_OK;
+}
+
+NS_IMETHODIMP FetchService::Observe(nsISupports* aSubject, const char* aTopic,
+                                    const char16_t* aData) {
+  FETCH_LOG(("FetchService::Observe topic: %s", aTopic));
+  AssertIsOnMainThread();
+  MOZ_ASSERT(!strcmp(aTopic, NS_IOSERVICE_OFFLINE_STATUS_TOPIC) ||
+             !strcmp(aTopic, "xpcom-shutdown"));
+
+  if (!strcmp(aTopic, "xpcom-shutdown")) {
+    // Going to shutdown, unregister the network status observer to avoid
+    // receiving
+    nsresult rv = UnregisterNetworkObserver();
+    NS_ENSURE_SUCCESS(rv, rv);
+    return NS_OK;
+  }
+
+  if (nsDependentString(aData).EqualsLiteral(NS_IOSERVICE_ONLINE)) {
+    mOffline = false;
+  } else {
+    mOffline = true;
+    // Network is offline, cancel running fetchs.
+    for (auto it = mFetchInstanceTable.begin(), end = mFetchInstanceTable.end();
+         it != end; ++it) {
+      it->GetData()->Cancel();
+    }
+    mFetchInstanceTable.Clear();
+  }
+  return NS_OK;
+}
 
 RefPtr<FetchServiceResponsePromise> FetchService::Fetch(
     SafeRefPtr<InternalRequest> aRequest, nsIChannel* aChannel) {
   MOZ_ASSERT(XRE_IsParentProcess());
   MOZ_ASSERT(NS_IsMainThread());
 
-  FETCH_LOG(("FetchService::Fetch aRequest[%p], aChannel[%p]",
-             aRequest.unsafeGetRawPtr(), aChannel));
+  FETCH_LOG(("FetchService::Fetch aRequest[%p], aChannel[%p], mOffline: %s",
+             aRequest.unsafeGetRawPtr(), aChannel,
+             mOffline ? "true" : "false"));
+
+  if (mOffline) {
+    FETCH_LOG(("FetchService::Fetch network offline"));
+    return NetworkErrorResponse(NS_ERROR_OFFLINE);
+  }
 
   // Create FetchInstance
   RefPtr<FetchInstance> fetch = MakeRefPtr<FetchInstance>(aRequest.clonePtr());
@@ -291,7 +381,10 @@ void FetchService::CancelFetch(
 
   auto entry = mFetchInstanceTable.Lookup(aResponsePromise);
   if (entry) {
+    // Notice any modifications here before entry.Remove() probably should be
+    // reflected to Observe() offline case.
     entry.Data()->Cancel();
+
     entry.Remove();
     FETCH_LOG(("FetchService::CancelFetch aResponsePromise[%p] is removed",
                aResponsePromise.get()));
diff --git a/dom/fetch/FetchService.h b/dom/fetch/FetchService.h
index ea83b02137f72..458ae11b7dffe 100644
--- a/dom/fetch/FetchService.h
+++ b/dom/fetch/FetchService.h
@@ -5,6 +5,7 @@
 #define _mozilla_dom_FetchService_h
 
 #include "nsIChannel.h"
+#include "nsIObserver.h"
 #include "nsTHashMap.h"
 #include "mozilla/ErrorResult.h"
 #include "mozilla/MozPromise.h"
@@ -41,9 +42,10 @@ using FetchServiceResponsePromise =
  * the FetchServiceResponsePromise would be resolved or rejected. The promise
  * consumers can set callbacks to handle the Fetch result.
  */
-class FetchService final {
+class FetchService final : public nsIObserver {
  public:
-  NS_INLINE_DECL_REFCOUNTING(FetchService)
+  NS_DECL_ISUPPORTS;
+  NS_DECL_NSIOBSERVER;
 
   static already_AddRefed<FetchService> GetInstance();
 
@@ -112,10 +114,15 @@ class FetchService final {
 
   ~FetchService();
 
+  nsresult RegisterNetworkObserver();
+  nsresult UnregisterNetworkObserver();
+
   // This is a container to manage the generated fetches.
   nsTHashMap<nsRefPtrHashKey<FetchServiceResponsePromise>,
              RefPtr<FetchInstance> >
       mFetchInstanceTable;
+  bool mObservingNetwork{false};
+  bool mOffline{false};
 };
 
 }  // namespace mozilla::dom

-- 
To stop receiving notification emails like this one, please contact
the administrator of this repository.


More information about the tor-commits mailing list