1 // Copyright 2014 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_SUPERVISED_USER_SUPERVISED_USER_SETTINGS_SERVICE_H_ 6 #define CHROME_BROWSER_SUPERVISED_USER_SUPERVISED_USER_SETTINGS_SERVICE_H_ 7 8 #include <string> 9 #include <vector> 10 11 #include "base/callback.h" 12 #include "base/memory/ref_counted.h" 13 #include "base/memory/scoped_ptr.h" 14 #include "base/prefs/pref_store.h" 15 #include "base/values.h" 16 #include "chrome/browser/supervised_user/supervised_users.h" 17 #include "components/keyed_service/core/keyed_service.h" 18 #include "sync/api/syncable_service.h" 19 20 class PersistentPrefStore; 21 class Profile; 22 23 namespace base { 24 class FilePath; 25 class SequencedTaskRunner; 26 } 27 28 // This class syncs supervised user settings from a server, which are mapped to 29 // preferences. The downloaded settings are persisted in a PrefStore (which is 30 // not directly hooked up to the PrefService; it's just used internally). 31 // Settings are key-value pairs, where the key uniquely identifies the setting. 32 // The value is a string containing a JSON serialization of an arbitrary value, 33 // which is the value of the setting. 34 // 35 // There are two kinds of settings handled by this class: Atomic and split 36 // settings. 37 // Atomic settings consist of a single key (which will be mapped to a pref key) 38 // and a single (arbitrary) value. 39 // Split settings encode a dictionary value and are stored as multiple Sync 40 // items, one for each dictionary entry. The key for each of these Sync items 41 // is the key of the split setting, followed by a separator (':') and the key 42 // for the dictionary entry. The value of the Sync item is the value of the 43 // dictionary entry. 44 // 45 // As an example, a split setting with key "Moose" and value 46 // { 47 // "foo": "bar", 48 // "baz": "blurp" 49 // } 50 // would be encoded as two sync items, one with key "Moose:foo" and value "bar", 51 // and one with key "Moose:baz" and value "blurp". 52 class SupervisedUserSettingsService : public KeyedService, 53 public syncer::SyncableService, 54 public PrefStore::Observer { 55 public: 56 // A callback whose first parameter is a dictionary containing all supervised 57 // user settings. If the dictionary is NULL, it means that the service is 58 // inactive, i.e. the user is not supervised. 59 typedef base::Callback<void(const base::DictionaryValue*)> SettingsCallback; 60 61 SupervisedUserSettingsService(); 62 virtual ~SupervisedUserSettingsService(); 63 64 // Initializes the service by loading its settings from a file underneath the 65 // |profile_path|. File I/O will be serialized via the 66 // |sequenced_task_runner|. If |load_synchronously| is true, the settings will 67 // be loaded synchronously, otherwise asynchronously. 68 void Init(base::FilePath profile_path, 69 base::SequencedTaskRunner* sequenced_task_runner, 70 bool load_synchronously); 71 72 // Initializes the service by loading its settings from the |pref_store|. 73 // Use this method in tests to inject a different PrefStore than the 74 // default one. 75 void Init(scoped_refptr<PersistentPrefStore> pref_store); 76 77 // Adds a callback to be called when supervised user settings are initially 78 // available, or when they change. 79 void Subscribe(const SettingsCallback& callback); 80 81 // Activates/deactivates the service. This is called by the 82 // SupervisedUserService when it is (de)activated. 83 void SetActive(bool active); 84 85 // Whether supervised user settings are available. 86 bool IsReady(); 87 88 // Clears all supervised user settings and items. 89 void Clear(); 90 91 // Constructs a key for a split supervised user setting from a prefix and a 92 // variable key. 93 static std::string MakeSplitSettingKey(const std::string& prefix, 94 const std::string& key); 95 96 // Uploads an item to the Sync server. Items are the same data structure as 97 // supervised user settings (i.e. key-value pairs, as described at the top of 98 // the file), but they are only uploaded (whereas supervised user settings are 99 // only downloaded), and never passed to the preference system. 100 // An example of an uploaded item is an access request to a blocked URL. 101 void UploadItem(const std::string& key, scoped_ptr<base::Value> value); 102 103 // Sets the setting with the given |key| to a copy of the given |value|. 104 void SetLocalSettingForTesting(const std::string& key, 105 scoped_ptr<base::Value> value); 106 107 // Public for testing. 108 static syncer::SyncData CreateSyncDataForSetting(const std::string& name, 109 const base::Value& value); 110 111 // KeyedService implementation: 112 virtual void Shutdown() OVERRIDE; 113 114 // SyncableService implementation: 115 virtual syncer::SyncMergeResult MergeDataAndStartSyncing( 116 syncer::ModelType type, 117 const syncer::SyncDataList& initial_sync_data, 118 scoped_ptr<syncer::SyncChangeProcessor> sync_processor, 119 scoped_ptr<syncer::SyncErrorFactory> error_handler) OVERRIDE; 120 virtual void StopSyncing(syncer::ModelType type) OVERRIDE; 121 virtual syncer::SyncDataList GetAllSyncData(syncer::ModelType type) const 122 OVERRIDE; 123 virtual syncer::SyncError ProcessSyncChanges( 124 const tracked_objects::Location& from_here, 125 const syncer::SyncChangeList& change_list) OVERRIDE; 126 127 // PrefStore::Observer implementation: 128 virtual void OnPrefValueChanged(const std::string& key) OVERRIDE; 129 virtual void OnInitializationCompleted(bool success) OVERRIDE; 130 131 private: 132 base::DictionaryValue* GetOrCreateDictionary(const std::string& key) const; 133 base::DictionaryValue* GetAtomicSettings() const; 134 base::DictionaryValue* GetSplitSettings() const; 135 base::DictionaryValue* GetQueuedItems() const; 136 137 // Returns the dictionary where a given Sync item should be stored, depending 138 // on whether the supervised user setting is atomic or split. In case of a 139 // split setting, the split setting prefix of |key| is removed, so that |key| 140 // can be used to update the returned dictionary. 141 base::DictionaryValue* GetDictionaryAndSplitKey(std::string* key) const; 142 143 // Returns a dictionary with all supervised user settings if the service is 144 // active, or NULL otherwise. 145 scoped_ptr<base::DictionaryValue> GetSettings(); 146 147 // Sends the settings to all subscribers. This method should be called by the 148 // subclass whenever the settings change. 149 void InformSubscribers(); 150 151 // Used for persisting the settings. Unlike other PrefStores, this one is not 152 // directly hooked up to the PrefService. 153 scoped_refptr<PersistentPrefStore> store_; 154 155 bool active_; 156 157 // A set of local settings that are fixed and not configured remotely. 158 scoped_ptr<base::DictionaryValue> local_settings_; 159 160 std::vector<SettingsCallback> subscribers_; 161 162 scoped_ptr<syncer::SyncChangeProcessor> sync_processor_; 163 scoped_ptr<syncer::SyncErrorFactory> error_handler_; 164 165 DISALLOW_COPY_AND_ASSIGN(SupervisedUserSettingsService); 166 }; 167 168 #endif // CHROME_BROWSER_SUPERVISED_USER_SUPERVISED_USER_SETTINGS_SERVICE_H_ 169