1 // Copyright 2019 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 CHROMEOS_COMPONENTS_SYNC_WIFI_WIFI_CONFIGURATION_BRIDGE_H_
6 #define CHROMEOS_COMPONENTS_SYNC_WIFI_WIFI_CONFIGURATION_BRIDGE_H_
7 
8 #include <map>
9 #include <memory>
10 #include <string>
11 #include <utility>
12 #include <vector>
13 
14 #include "base/macros.h"
15 #include "base/memory/weak_ptr.h"
16 #include "base/time/time.h"
17 #include "base/timer/timer.h"
18 #include "chromeos/components/sync_wifi/network_identifier.h"
19 #include "chromeos/network/network_configuration_observer.h"
20 #include "chromeos/network/network_metadata_observer.h"
21 #include "components/sync/base/model_type.h"
22 #include "components/sync/model/model_type_store.h"
23 #include "components/sync/model/model_type_sync_bridge.h"
24 
25 class PrefRegistrySimple;
26 class PrefService;
27 
28 namespace syncer {
29 class ModelTypeChangeProcessor;
30 }  // namespace syncer
31 
32 namespace chromeos {
33 
34 class NetworkConfigurationHandler;
35 class NetworkMetadataStore;
36 
37 namespace sync_wifi {
38 
39 const char kIsFirstRun[] = "sync_wifi.is_first_run";
40 
41 class LocalNetworkCollector;
42 class SyncedNetworkMetricsLogger;
43 class SyncedNetworkUpdater;
44 class TimerFactory;
45 
46 // Receives updates to network configurations from the Chrome sync back end and
47 // from the system network stack and keeps both lists in sync.
48 class WifiConfigurationBridge : public syncer::ModelTypeSyncBridge,
49                                 public NetworkConfigurationObserver,
50                                 public NetworkMetadataObserver {
51  public:
52   WifiConfigurationBridge(
53       SyncedNetworkUpdater* synced_network_updater,
54       LocalNetworkCollector* local_network_collector,
55       NetworkConfigurationHandler* network_configuration_handler,
56       SyncedNetworkMetricsLogger* metrics_recorder,
57       TimerFactory* timer_factory,
58       PrefService* pref_service,
59       std::unique_ptr<syncer::ModelTypeChangeProcessor> change_processor,
60       syncer::OnceModelTypeStoreFactory create_store_callback);
61   ~WifiConfigurationBridge() override;
62 
63   static void RegisterPrefs(PrefRegistrySimple* registry);
64 
65   // syncer::ModelTypeSyncBridge:
66   std::unique_ptr<syncer::MetadataChangeList> CreateMetadataChangeList()
67       override;
68   base::Optional<syncer::ModelError> MergeSyncData(
69       std::unique_ptr<syncer::MetadataChangeList> metadata_change_list,
70       syncer::EntityChangeList entity_data) override;
71   base::Optional<syncer::ModelError> ApplySyncChanges(
72       std::unique_ptr<syncer::MetadataChangeList> metadata_change_list,
73       syncer::EntityChangeList entity_changes) override;
74   void GetData(StorageKeyList storage_keys, DataCallback callback) override;
75   void GetAllDataForDebugging(DataCallback callback) override;
76   std::string GetClientTag(const syncer::EntityData& entity_data) override;
77   std::string GetStorageKey(const syncer::EntityData& entity_data) override;
78 
79   // NetworkMetadataObserver:
80   void OnFirstConnectionToNetwork(const std::string& guid) override;
81   void OnNetworkCreated(const std::string& guid) override;
82   void OnNetworkUpdate(const std::string& guid,
83                        base::DictionaryValue* set_properties) override;
84 
85   // NetworkConfigurationObserver::
86   void OnBeforeConfigurationRemoved(const std::string& service_path,
87                                     const std::string& guid) override;
88   void OnConfigurationRemoved(const std::string& service_path,
89                               const std::string& guid) override;
90   void OnShuttingDown() override;
91 
92   // Comes from |entries_| the in-memory map.
93   std::vector<NetworkIdentifier> GetAllIdsForTesting();
94 
95   void SetNetworkMetadataStore(
96       base::WeakPtr<NetworkMetadataStore> network_metadata_store);
97 
98  private:
99   void Commit(std::unique_ptr<syncer::ModelTypeStore::WriteBatch> batch);
100 
101   // Callbacks for ModelTypeStore.
102   void OnStoreCreated(const base::Optional<syncer::ModelError>& error,
103                       std::unique_ptr<syncer::ModelTypeStore> store);
104   void OnReadAllData(
105       const base::Optional<syncer::ModelError>& error,
106       std::unique_ptr<syncer::ModelTypeStore::RecordList> records);
107   void OnReadAllMetadata(const base::Optional<syncer::ModelError>& error,
108                          std::unique_ptr<syncer::MetadataBatch> metadata_batch);
109   void OnCommit(const base::Optional<syncer::ModelError>& error);
110 
111   void OnGetAllSyncableNetworksResult(
112       std::unique_ptr<syncer::MetadataChangeList> metadata_change_list,
113       syncer::EntityChangeList change_list,
114       std::vector<sync_pb::WifiConfigurationSpecifics> local_network_list);
115 
116   void SaveNetworkToSync(
117       base::Optional<sync_pb::WifiConfigurationSpecifics> proto);
118   void RemoveNetworkFromSync(
119       base::Optional<sync_pb::WifiConfigurationSpecifics> proto);
120 
121   // Starts an async request to serialize a network to a proto and save to sync.
122   void OnNetworkConfiguredDelayComplete(const std::string& network_guid);
123 
124   bool IsLastUpdateFromSync(const std::string& network_guid);
125 
126   // An in-memory list of the proto's that mirrors what is on the sync server.
127   // This gets updated when changes are received from the server and after local
128   // changes have been committed.  On initialization of this class, it is
129   // populated with the contents of |store_|.
130   base::flat_map<std::string, sync_pb::WifiConfigurationSpecifics> entries_;
131 
132   // Map of network |guid| to |storage_key|.  After a network is deleted, we
133   // no longer have access to its metadata so this stores the necessary
134   // information to delete it from sync.
135   base::flat_map<std::string, std::string> pending_deletes_;
136 
137   // Holds on to timers that are started immediately after a network is
138   // configured so we can wait until the first connection attempt is complete.
139   base::flat_map<std::string, std::unique_ptr<base::OneShotTimer>>
140       network_guid_to_timer_map_;
141 
142   // The on disk store of WifiConfigurationSpecifics protos that mirrors what
143   // is on the sync server.  This gets updated when changes are received from
144   // the server and after local changes have been committed to the server.
145   std::unique_ptr<syncer::ModelTypeStore> store_;
146 
147   SyncedNetworkUpdater* synced_network_updater_;
148   LocalNetworkCollector* local_network_collector_;
149   NetworkConfigurationHandler* network_configuration_handler_;
150   SyncedNetworkMetricsLogger* metrics_recorder_;
151   TimerFactory* timer_factory_;
152   PrefService* pref_service_;
153   base::WeakPtr<NetworkMetadataStore> network_metadata_store_;
154 
155   base::WeakPtrFactory<WifiConfigurationBridge> weak_ptr_factory_{this};
156 
157   DISALLOW_COPY_AND_ASSIGN(WifiConfigurationBridge);
158 };
159 
160 }  // namespace sync_wifi
161 
162 }  // namespace chromeos
163 
164 #endif  // CHROMEOS_COMPONENTS_SYNC_WIFI_WIFI_CONFIGURATION_BRIDGE_H_
165