blob: 5cd3a6d128d67f0d012e862a1ad38174e3f141eb [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 <memory>
#include <string>
#include <vector>
#include <base/callback_forward.h>
#include <base/compiler_specific.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;
virtual void SetBool(const std::string& name, bool value) = 0;
};
class PrefsSourceInterface;
using PrefsSourceInterfaceVector =
std::vector<std::unique_ptr<PrefsSourceInterface>>;
// Result of a pref file read operation.
struct PrefReadResult {
std::string value; // The value that was read.
std::string source_desc; // Where |value| came from, for logging.
};
// Interface for readable sources of preferences.
class PrefsSourceInterface {
public:
virtual ~PrefsSourceInterface() {}
// Gets a description of this source suitable for logging.
virtual std::string GetDescription() const = 0;
// Reads a pref named |name| from this source into the given string.
virtual bool ReadPrefString(const std::string& name,
std::string* value_out) = 0;
};
// Interface for readable and writable storage of preferences.
class PrefsStoreInterface : public PrefsSourceInterface {
public:
// Callback type for Watch(). |name| refers to the updated preference.
using ChangeCallback = base::Callback<void(const std::string& name)>;
// Writes a pref named |name| to this store.
virtual bool WritePrefString(const std::string& name,
const std::string& value) = 0;
// Starts watching for changes in this store and call |callback| with changes.
// If called multiple times, only the last callback will be notified.
// Returns true on success.
virtual bool Watch(const ChangeCallback& callback) = 0;
};
// PrefsInterface implementation that reads and writes prefs from/to disk and
// from libcros_config.
// 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(const TestApi&) = delete;
TestApi& operator=(const TestApi&) = delete;
~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
};
Prefs();
Prefs(const Prefs&) = delete;
Prefs& operator=(const Prefs&) = delete;
~Prefs() override;
// Returns the default writable store of prefs, to be passed to Init().
static std::unique_ptr<PrefsStoreInterface> GetDefaultStore();
// Returns the default sources where prefs are stored, to be passed to Init().
static PrefsSourceInterfaceVector GetDefaultSources();
// Initialize the preference store and sources. The |store| takes highest
// precedence when reading preferences, followed by the |sources|, in order.
// The |store| is also used to write preferences and watched for changes.
bool Init(std::unique_ptr<PrefsStoreInterface> store,
PrefsSourceInterfaceVector sources);
// 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;
void SetBool(const std::string& name, bool value) override;
private:
// Handle changes to pref values in |pref_store_|.
void HandlePrefChanged(const std::string& name);
// Reads string values of pref given by |name| from all the sources in
// |pref_sources_| 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 source.
void GetPrefResults(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 |pref_store_|, updates |last_write_time_|,
// and clears |prefs_to_write_|.
void WritePrefs();
// The pref store is the highest precedence source of pref values and the
// writable sink for preferences.
std::unique_ptr<PrefsStoreInterface> pref_store_;
// List of pref sources to read from, in order of precedence.
// A value read from the first path will be used instead of values from the
// other paths.
PrefsSourceInterfaceVector pref_sources_;
base::ObserverList<PrefsObserver> observers_;
// Calls WritePrefs().
base::OneShotTimer 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_;
};
} // namespace power_manager
#endif // POWER_MANAGER_COMMON_PREFS_H_