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