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_CHROMEOS_POLICY_SERVER_BACKED_STATE_KEYS_BROKER_H_
6#define CHROME_BROWSER_CHROMEOS_POLICY_SERVER_BACKED_STATE_KEYS_BROKER_H_
7
8#include <string>
9#include <vector>
10
11#include "base/callback.h"
12#include "base/callback_list.h"
13#include "base/macros.h"
14#include "base/memory/ref_counted.h"
15#include "base/memory/weak_ptr.h"
16
17namespace base {
18class TaskRunner;
19}
20
21namespace chromeos {
22class SessionManagerClient;
23}
24
25namespace policy {
26
27// Brokers server-backed FRE state keys for the device. Retrieves them from
28// session manager via DBus and refreshes them periodically. Consumers can
29// register callbacks to invoke when the state keys change.
30class ServerBackedStateKeysBroker {
31 public:
32  typedef scoped_ptr<base::CallbackList<void()>::Subscription> Subscription;
33  typedef base::Callback<void(const std::vector<std::string>&, bool)>
34      StateKeysCallback;
35
36  ServerBackedStateKeysBroker(
37      chromeos::SessionManagerClient* session_manager_client,
38      scoped_refptr<base::TaskRunner> delayed_task_runner);
39  ~ServerBackedStateKeysBroker();
40
41  // Registers a callback to be invoked whenever the state keys get updated.
42  // Note that consuming code needs to hold on to the returned Subscription as
43  // long as it wants to receive the callback. If the state keys haven't been
44  // requested yet, calling this will also trigger their initial fetch.
45  Subscription RegisterUpdateCallback(const base::Closure& callback);
46
47  // Requests state keys asynchronously. Invokes the passed callback exactly
48  // once (unless |this| gets destroyed before the callback happens), with the
49  // current state keys passed as a parameter to the callback. If there's a
50  // problem determining the state keys, the passed vector will be empty.
51  void RequestStateKeys(const StateKeysCallback& callback);
52
53  // Get the set of current state keys. Empty if state keys are unavailable
54  // or pending retrieval.
55  const std::vector<std::string>& state_keys() const { return state_keys_; }
56
57  // Returns the state key for the current point in time. Returns an empty
58  // string if state keys are unavailable or pending retrieval.
59  std::string current_state_key() const {
60    return state_keys_.empty() ? std::string() : state_keys_.front();
61  }
62
63  // Whether state key retrieval is pending.
64  bool pending() const { return !initial_retrieval_completed_; }
65
66  // Whether state keys are available.
67  bool available() const { return !state_keys_.empty(); }
68
69 private:
70  // Asks |session_manager_client_| to provide current state keys..
71  void FetchStateKeys();
72
73  // Stores newly-received state keys and notifies consumers.
74  void StoreStateKeys(const std::vector<std::string>& state_keys,
75                      bool first_boot);
76
77  chromeos::SessionManagerClient* session_manager_client_;
78
79  scoped_refptr<base::TaskRunner> delayed_task_runner_;
80
81  // The current set of state keys.
82  std::vector<std::string> state_keys_;
83
84  // Set to true on first run after factory reset.
85  bool first_boot_;
86
87  // Whether a request for state keys is pending.
88  bool requested_;
89
90  // Whether the initial retrieval operation completed.
91  bool initial_retrieval_completed_;
92
93  // List of callbacks to receive update notifications.
94  base::CallbackList<void()> update_callbacks_;
95
96  // List of pending one-shot state key request callbacks.
97  std::vector<StateKeysCallback> request_callbacks_;
98
99  base::WeakPtrFactory<ServerBackedStateKeysBroker> weak_factory_;
100
101  DISALLOW_COPY_AND_ASSIGN(ServerBackedStateKeysBroker);
102};
103
104}  // namespace policy
105
106#endif  // CHROME_BROWSER_CHROMEOS_POLICY_SERVER_BACKED_STATE_KEYS_BROKER_H_
107