cloud_external_data_policy_observer.h revision a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7
1// Copyright 2013 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_CLOUD_EXTERNAL_DATA_POLICY_OBSERVER_H_
6#define CHROME_BROWSER_CHROMEOS_POLICY_CLOUD_EXTERNAL_DATA_POLICY_OBSERVER_H_
7
8#include <map>
9#include <string>
10
11#include "base/basictypes.h"
12#include "base/compiler_specific.h"
13#include "base/memory/linked_ptr.h"
14#include "base/memory/scoped_ptr.h"
15#include "base/memory/weak_ptr.h"
16#include "chrome/browser/chromeos/policy/device_local_account_policy_service.h"
17#include "chrome/browser/chromeos/settings/cros_settings.h"
18#include "components/policy/core/common/policy_map.h"
19#include "content/public/browser/notification_observer.h"
20#include "content/public/browser/notification_registrar.h"
21
22namespace chromeos {
23class UserManager;
24}
25
26namespace policy {
27
28// Helper for implementing policies referencing external data: This class
29// observes a given |policy_| and fetches the external data that it references
30// for all users on the device. Notifications are emitted when an external data
31// reference is set, cleared or an external data fetch completes successfully.
32//
33// State is kept at runtime only: External data references that already exist
34// when the class is instantiated are considered new, causing a notification to
35// be emitted that an external data reference has been set and the referenced
36// external data to be fetched.
37class CloudExternalDataPolicyObserver
38    : public content::NotificationObserver,
39      public DeviceLocalAccountPolicyService::Observer {
40 public:
41  class Delegate {
42   public:
43    // Invoked when an external data reference is set for |user_id|.
44    virtual void OnExternalDataSet(const std::string& policy,
45                                   const std::string& user_id);
46
47    // Invoked when the external data reference is cleared for |user_id|.
48    virtual void OnExternalDataCleared(const std::string& policy,
49                                       const std::string& user_id);
50
51    // Invoked when the external data referenced for |user_id| has been fetched.
52    // Failed fetches are retried and the method is called only when a fetch
53    // eventually succeeds. If a fetch fails permanently (e.g. because the
54    // external data reference specifies an invalid URL), the method is not
55    // called at all.
56    virtual void OnExternalDataFetched(const std::string& policy,
57                                       const std::string& user_id,
58                                       scoped_ptr<std::string> data);
59
60   protected:
61    virtual ~Delegate();
62  };
63
64  CloudExternalDataPolicyObserver(
65      chromeos::CrosSettings* cros_settings,
66      chromeos::UserManager* user_manager,
67      DeviceLocalAccountPolicyService* device_local_account_policy_service,
68      const std::string& policy,
69      Delegate* delegate);
70  virtual ~CloudExternalDataPolicyObserver();
71
72  void Init();
73
74  // content::NotificationObserver:
75  virtual void Observe(int type,
76                       const content::NotificationSource& source,
77                       const content::NotificationDetails& details) OVERRIDE;
78
79  // DeviceLocalAccountPolicyService::Observer:
80  virtual void OnPolicyUpdated(const std::string& user_id) OVERRIDE;
81  virtual void OnDeviceLocalAccountsChanged() OVERRIDE;
82
83 private:
84  // Helper class that observes |policy_| for a logged-in user.
85  class PolicyServiceObserver;
86
87  void RetrieveDeviceLocalAccounts();
88
89  // Handles the new policy map |entry| for |user_id| by canceling any external
90  // data fetch currently in progress, emitting a notification that an external
91  // data reference has been cleared (if |entry| is NULL) or set (otherwise),
92  // starting a new external data fetch in the latter case.
93  void HandleExternalDataPolicyUpdate(const std::string& user_id,
94                                      const PolicyMap::Entry* entry);
95
96  void OnExternalDataFetched(const std::string& user_id,
97                             scoped_ptr<std::string> data);
98
99  // A map from each device-local account user ID to its current policy map
100  // entry for |policy_|.
101  typedef std::map<std::string, PolicyMap::Entry> DeviceLocalAccountEntryMap;
102  DeviceLocalAccountEntryMap device_local_account_entries_;
103
104  // A map from each logged-in user to the helper that observes |policy_| in the
105  // user's PolicyService.
106  typedef std::map<std::string, linked_ptr<PolicyServiceObserver> >
107      LoggedInUserObserverMap;
108  LoggedInUserObserverMap logged_in_user_observers_;
109
110  chromeos::CrosSettings* cros_settings_;
111  chromeos::UserManager* user_manager_;
112  DeviceLocalAccountPolicyService* device_local_account_policy_service_;
113
114  // The policy that |this| observes.
115  std::string policy_;
116
117  Delegate* delegate_;
118
119  content::NotificationRegistrar notification_registrar_;
120  scoped_ptr<chromeos::CrosSettings::ObserverSubscription>
121      device_local_accounts_subscription_;
122
123  // A map from user ID to a base::WeakPtr for each external data fetch
124  // currently in progress. This allows fetches to be effectively be canceled by
125  // invalidating the pointers.
126  typedef base::WeakPtrFactory<CloudExternalDataPolicyObserver>
127      WeakPtrFactory;
128  typedef std::map<std::string, linked_ptr<WeakPtrFactory> > FetchWeakPtrMap;
129  FetchWeakPtrMap fetch_weak_ptrs_;
130
131  base::WeakPtrFactory<CloudExternalDataPolicyObserver> weak_factory_;
132
133  DISALLOW_COPY_AND_ASSIGN(CloudExternalDataPolicyObserver);
134};
135
136}  // namespace policy
137
138#endif  // CHROME_BROWSER_CHROMEOS_POLICY_CLOUD_EXTERNAL_DATA_POLICY_OBSERVER_H_
139