1 // Copyright 2015 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 #ifndef CHROME_BROWSER_EXTENSIONS_API_SETTINGS_PRIVATE_SETTINGS_PRIVATE_EVENT_ROUTER_H_
6 #define CHROME_BROWSER_EXTENSIONS_API_SETTINGS_PRIVATE_SETTINGS_PRIVATE_EVENT_ROUTER_H_
7 
8 #include <map>
9 #include <memory>
10 
11 #include "base/macros.h"
12 #include "base/memory/weak_ptr.h"
13 #include "chrome/browser/extensions/api/settings_private/generated_pref.h"
14 #include "chrome/browser/extensions/api/settings_private/prefs_util.h"
15 #include "components/keyed_service/core/keyed_service.h"
16 #include "components/prefs/pref_change_registrar.h"
17 #include "extensions/browser/event_router.h"
18 
19 #if defined(OS_CHROMEOS)
20 #include "chrome/browser/chromeos/settings/cros_settings.h"
21 #endif
22 
23 namespace content {
24 class BrowserContext;
25 }
26 
27 namespace extensions {
28 
29 // This is an event router that will observe listeners to pref changes on the
30 // appropriate pref service(s) and notify listeners on the JavaScript
31 // settingsPrivate API.
32 class SettingsPrivateEventRouter
33     : public KeyedService,
34       public EventRouter::Observer,
35       public settings_private::GeneratedPref::Observer {
36  public:
37   static SettingsPrivateEventRouter* Create(
38       content::BrowserContext* browser_context);
39   ~SettingsPrivateEventRouter() override;
40 
41   // settings_private::GeneratedPref::Observer implementation.
42   void OnGeneratedPrefChanged(const std::string& pref_name) override;
43 
context_for_test()44   content::BrowserContext* context_for_test() { return context_; }
45 
46  protected:
47   explicit SettingsPrivateEventRouter(content::BrowserContext* context);
48 
49   // KeyedService overrides:
50   void Shutdown() override;
51 
52   // EventRouter::Observer overrides:
53   void OnListenerAdded(const EventListenerInfo& details) override;
54   void OnListenerRemoved(const EventListenerInfo& details) override;
55 
56   // This registrar monitors for user prefs changes.
57   PrefChangeRegistrar user_prefs_registrar_;
58 
59   // This registrar monitors for local state changes.
60   PrefChangeRegistrar local_state_registrar_;
61 
62  private:
63   // Decide if we should listen for pref changes or not. If there are any
64   // JavaScript listeners registered for the onPrefsChanged event, then we
65   // want to register for change notification from the PrefChangeRegistrar.
66   // Otherwise, we want to unregister and not be listening for pref changes.
67   void StartOrStopListeningForPrefsChanges();
68 
69   void OnPreferenceChanged(const std::string& pref_name);
70 
71   // Sends a pref change to any listeners (if they exist; no-ops otherwise).
72   void SendPrefChange(const std::string& pref_name);
73 
74   PrefChangeRegistrar* FindRegistrarForPref(const std::string& pref_name);
75 
76 #if defined(OS_CHROMEOS)
77   using SubscriptionMap =
78       std::map<std::string,
79                std::unique_ptr<chromeos::CrosSettings::ObserverSubscription>>;
80   SubscriptionMap cros_settings_subscription_map_;
81 #endif
82 
83   content::BrowserContext* const context_;
84   bool listening_ = false;
85 
86   std::unique_ptr<PrefsUtil> prefs_util_;
87 
88   base::WeakPtrFactory<SettingsPrivateEventRouter> weak_ptr_factory_{this};
89 
90   DISALLOW_COPY_AND_ASSIGN(SettingsPrivateEventRouter);
91 };
92 
93 }  // namespace extensions
94 
95 #endif  // CHROME_BROWSER_EXTENSIONS_API_SETTINGS_PRIVATE_SETTINGS_PRIVATE_EVENT_ROUTER_H_
96