Bug 1942239 - Add option to explicitly enable incremental origin initialization in...
[gecko.git] / toolkit / components / antitracking / SettingsChangeObserver.cpp
blob138016c6abe899a5bf4c13955feb62f7f7d62e16
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 file,
5 * You can obtain one at http://mozilla.org/MPL/2.0/. */
7 #include "SettingsChangeObserver.h"
8 #include "ContentBlockingUserInteraction.h"
10 #include "mozilla/Services.h"
11 #include "mozilla/Preferences.h"
12 #include "nsIObserverService.h"
13 #include "nsIPermission.h"
14 #include "nsTArray.h"
16 using namespace mozilla;
18 namespace {
20 MOZ_RUNINIT UniquePtr<
21 nsTArray<SettingsChangeObserver::AntiTrackingSettingsChangedCallback>>
22 gSettingsChangedCallbacks;
26 NS_IMPL_ISUPPORTS(SettingsChangeObserver, nsIObserver)
28 NS_IMETHODIMP SettingsChangeObserver::Observe(nsISupports* aSubject,
29 const char* aTopic,
30 const char16_t* aData) {
31 if (!strcmp(aTopic, "xpcom-shutdown")) {
32 nsCOMPtr<nsIObserverService> obs = services::GetObserverService();
33 if (obs) {
34 obs->RemoveObserver(this, "perm-added");
35 obs->RemoveObserver(this, "perm-changed");
36 obs->RemoveObserver(this, "perm-cleared");
37 obs->RemoveObserver(this, "perm-deleted");
38 obs->RemoveObserver(this, "xpcom-shutdown");
40 Preferences::UnregisterPrefixCallback(
41 SettingsChangeObserver::PrivacyPrefChanged,
42 "browser.contentblocking.");
43 Preferences::UnregisterPrefixCallback(
44 SettingsChangeObserver::PrivacyPrefChanged, "network.cookie.");
45 Preferences::UnregisterPrefixCallback(
46 SettingsChangeObserver::PrivacyPrefChanged, "privacy.");
48 gSettingsChangedCallbacks = nullptr;
50 } else {
51 nsCOMPtr<nsIPermission> perm = do_QueryInterface(aSubject);
52 if (perm) {
53 nsAutoCString type;
54 nsresult rv = perm->GetType(type);
55 if (NS_WARN_IF(NS_FAILED(rv)) || type.Equals(USER_INTERACTION_PERM)) {
56 // Ignore failures or notifications that have been sent because of
57 // user interactions.
58 return NS_OK;
62 RunAntiTrackingSettingsChangedCallbacks();
65 return NS_OK;
68 // static
69 void SettingsChangeObserver::PrivacyPrefChanged(const char* aPref,
70 void* aClosure) {
71 RunAntiTrackingSettingsChangedCallbacks();
74 // static
75 void SettingsChangeObserver::RunAntiTrackingSettingsChangedCallbacks() {
76 if (gSettingsChangedCallbacks) {
77 for (auto& callback : *gSettingsChangedCallbacks) {
78 callback();
83 // static
84 void SettingsChangeObserver::OnAntiTrackingSettingsChanged(
85 const SettingsChangeObserver::AntiTrackingSettingsChangedCallback&
86 aCallback) {
87 static bool initialized = false;
88 if (!initialized) {
89 // It is possible that while we have some data in our cache, something
90 // changes in our environment that causes the anti-tracking checks below to
91 // change their response. Therefore, we need to clear our cache when we
92 // detect a related change.
93 Preferences::RegisterPrefixCallback(
94 SettingsChangeObserver::PrivacyPrefChanged, "browser.contentblocking.");
95 Preferences::RegisterPrefixCallback(
96 SettingsChangeObserver::PrivacyPrefChanged, "network.cookie.");
97 Preferences::RegisterPrefixCallback(
98 SettingsChangeObserver::PrivacyPrefChanged, "privacy.");
100 nsCOMPtr<nsIObserverService> obs = services::GetObserverService();
101 if (obs) {
102 RefPtr<SettingsChangeObserver> observer = new SettingsChangeObserver();
103 obs->AddObserver(observer, "perm-added", false);
104 obs->AddObserver(observer, "perm-changed", false);
105 obs->AddObserver(observer, "perm-cleared", false);
106 obs->AddObserver(observer, "perm-deleted", false);
107 obs->AddObserver(observer, "xpcom-shutdown", false);
110 gSettingsChangedCallbacks =
111 MakeUnique<nsTArray<AntiTrackingSettingsChangedCallback>>();
113 initialized = true;
116 gSettingsChangedCallbacks->AppendElement(aCallback);