blob: ff73e1ac782771dd24c5262932f72db917cc8ab4 [file] [log] [blame]
// Copyright (c) 2012 The Chromium OS Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef POWER_MANAGER_COMMON_PREFS_H_
#define POWER_MANAGER_COMMON_PREFS_H_
#include <stdint.h>
#include <map>
#include <string>
#include <vector>
#include <base/compiler_specific.h>
#include <base/files/file_path.h>
#include <base/files/file_path_watcher.h>
#include <base/memory/linked_ptr.h>
#include <base/observer_list.h>
#include <base/time/time.h>
#include <base/timer/timer.h>
namespace power_manager {
class PrefsObserver;
// Interface for reading and writing preferences.
class PrefsInterface {
public:
virtual ~PrefsInterface() {}
// Adds or removes an observer.
virtual void AddObserver(PrefsObserver* observer) = 0;
virtual void RemoveObserver(PrefsObserver* observer) = 0;
// Reads settings and returns true on success.
virtual bool GetString(const std::string& name, std::string* value) = 0;
virtual bool GetInt64(const std::string& name, int64_t* value) = 0;
virtual bool GetDouble(const std::string& name, double* value) = 0;
virtual bool GetBool(const std::string& name, bool* value) = 0;
// Writes settings (possibly asynchronously, although any deferred
// changes will be reflected in Get*() calls).
virtual void SetString(const std::string& name, const std::string& value) = 0;
virtual void SetInt64(const std::string& name, int64_t value) = 0;
virtual void SetDouble(const std::string& name, double value) = 0;
};
// PrefsInterface implementation that reads and writes prefs from/to disk.
// Multiple directories are supported; this allows a default set of prefs
// to be placed on the readonly root partition and a second set of
// prefs under /var to be overlaid and changed at runtime.
class Prefs : public PrefsInterface {
public:
// Helper class for tests.
class TestApi {
public:
explicit TestApi(Prefs* prefs);
~TestApi();
void set_write_interval(base::TimeDelta interval) {
prefs_->write_interval_ = interval;
}
// Calls HandleWritePrefsTimeout(). Returns false if the timeout
// wasn't set.
bool TriggerWriteTimeout();
private:
Prefs* prefs_; // weak
DISALLOW_COPY_AND_ASSIGN(TestApi);
};
Prefs();
virtual ~Prefs();
// Earlier directories in |pref_paths_| take precedence over later ones. Only
// the first directory is watched for changes.
bool Init(const std::vector<base::FilePath>& pref_paths);
// PrefsInterface implementation:
void AddObserver(PrefsObserver* observer) override;
void RemoveObserver(PrefsObserver* observer) override;
bool GetString(const std::string& name, std::string* value) override;
bool GetInt64(const std::string& name, int64_t* value) override;
bool GetDouble(const std::string& name, double* value) override;
bool GetBool(const std::string& name, bool* value) override;
void SetString(const std::string& name, const std::string& value) override;
void SetInt64(const std::string& name, int64_t value) override;
void SetDouble(const std::string& name, double value) override;
private:
typedef std::map<std::string, linked_ptr<base::FilePathWatcher>>
FileWatcherMap;
// Result of a pref file read operation.
struct PrefReadResult {
std::string value; // The value that was read.
std::string path; // The pref file from which |value| was read.
};
// Called by |file_watcher_| when a pref is changed. Notifies |observers_|.
void HandleFileChanged(const base::FilePath& path, bool error);
// Reads contents of pref files given by |name| from all the paths in
// |pref_paths_| in order, where they exist. Strips them of whitespace.
// Stores each read result in |results|.
// If |read_all| is true, it will attempt to read from all pref paths.
// Otherwise it will return after successfully reading one pref file.
void GetPrefStrings(const std::string& name,
bool read_all,
std::vector<PrefReadResult>* results);
// Calls WritePrefs() immediately if prefs haven't been written to disk
// recently. Otherwise, schedules HandleWritePrefsTimeout() if it isn't
// already scheduled.
void ScheduleWrite();
// Writes |prefs_to_write_| to the first path in |pref_paths_|, updates
// |last_write_time_|, and clears |prefs_to_write_|.
void WritePrefs();
// Updates |file_watchers_| to contain a watcher for every file currently in
// |dir|.
void UpdateFileWatchers(const base::FilePath& dir);
// List of file paths to read from, in order of precedence.
// A value read from the first path will be used instead of values from the
// other paths.
std::vector<base::FilePath> pref_paths_;
base::ObserverList<PrefsObserver> observers_;
// For notification of updates to pref files.
base::FilePathWatcher dir_watcher_;
// Map from pref file basenames to base::FilePathWatchers.
FileWatcherMap file_watchers_;
// Calls WritePrefs().
base::OneShotTimer<Prefs> write_prefs_timer_;
// Last time at which WritePrefs() was called.
base::TimeTicks last_write_time_;
// Minimum time between prefs getting written to disk.
base::TimeDelta write_interval_;
// Map from name to stringified value of prefs that need to be written to
// the first path in |pref_paths_|.
std::map<std::string, std::string> prefs_to_write_;
DISALLOW_COPY_AND_ASSIGN(Prefs);
};
} // namespace power_manager
#endif // POWER_MANAGER_COMMON_PREFS_H_