11e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)// Copyright 2013 The Chromium Authors. All rights reserved.
25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file.
45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//
55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// A helper class that assists preferences in firing notifications when lists
65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// or dictionaries are changed.
75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
81e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)#ifndef BASE_PREFS_SCOPED_USER_PREF_UPDATE_H_
91e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)#define BASE_PREFS_SCOPED_USER_PREF_UPDATE_H_
105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <string>
125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/basictypes.h"
141e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)#include "base/prefs/base_prefs_export.h"
152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/prefs/pref_service.h"
165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/threading/non_thread_safe.h"
175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/values.h"
185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class PrefService;
205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace base {
225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class DictionaryValue;
235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class ListValue;
245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace subtle {
275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Base class for ScopedUserPrefUpdateTemplate that contains the parts
295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// that do not depend on ScopedUserPrefUpdateTemplate's template parameter.
305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//
315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// We need this base class mostly for making it a friend of PrefService
325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// and getting access to PrefService::GetMutableUserPref and
335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// PrefService::ReportUserPrefChanged.
341e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)class BASE_PREFS_EXPORT ScopedUserPrefUpdateBase : public base::NonThreadSafe {
355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) protected:
365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ScopedUserPrefUpdateBase(PrefService* service, const char* path);
375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Calls Notify().
395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ~ScopedUserPrefUpdateBase();
405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Sets |value_| to |service_|->GetMutableUserPref and returns it.
425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  base::Value* GetValueOfType(base::Value::Type type);
435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private:
455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // If |value_| is not null, triggers a notification of PrefObservers and
465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // resets |value_|.
475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void Notify();
485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Weak pointer.
505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  PrefService* service_;
515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Path of the preference being updated.
525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::string path_;
535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Cache of value from user pref store (set between Get() and Notify() calls).
545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  base::Value* value_;
555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(ScopedUserPrefUpdateBase);
575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace subtle
605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Class to support modifications to DictionaryValues and ListValues while
625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// guaranteeing that PrefObservers are notified of changed values.
635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//
645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// This class may only be used on the UI thread as it requires access to the
655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// PrefService.
665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)template <typename T, base::Value::Type type_enum_value>
675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class ScopedUserPrefUpdate : public subtle::ScopedUserPrefUpdateBase {
685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public:
695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ScopedUserPrefUpdate(PrefService* service, const char* path)
705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      : ScopedUserPrefUpdateBase(service, path) {}
715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Triggers an update notification if Get() was called.
735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual ~ScopedUserPrefUpdate() {}
745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Returns a mutable |T| instance that
765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // - is already in the user pref store, or
775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // - is (silently) created and written to the user pref store if none existed
785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  //   before.
795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  //
805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Calling Get() implies that an update notification is necessary at
815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // destruction time.
825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  //
835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // The ownership of the return value remains with the user pref store.
845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Virtual so it can be overriden in subclasses that transform the value
855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // before returning it (for example to return a subelement of a dictionary).
865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual T* Get() {
875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return static_cast<T*>(GetValueOfType(type_enum_value));
885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  T& operator*() {
915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return *Get();
925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  T* operator->() {
955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return Get();
965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private:
995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(ScopedUserPrefUpdate);
1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
102eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochtypedef ScopedUserPrefUpdate<base::DictionaryValue,
103eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch                             base::Value::TYPE_DICTIONARY>
1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    DictionaryPrefUpdate;
105eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochtypedef ScopedUserPrefUpdate<base::ListValue, base::Value::TYPE_LIST>
106eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    ListPrefUpdate;
1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1081e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)#endif  // BASE_PREFS_SCOPED_USER_PREF_UPDATE_H_
109