Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(35)

Side by Side Diff: chrome/browser/policy/async_policy_provider.cc

Issue 92263002: Move AsyncPolicyProvider, etc. to components/policy/. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: rebase Created 7 years ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
(Empty)
1 // Copyright (c) 2012 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 #include "chrome/browser/policy/async_policy_provider.h"
6
7 #include "base/bind.h"
8 #include "base/bind_helpers.h"
9 #include "base/location.h"
10 #include "base/message_loop/message_loop.h"
11 #include "base/message_loop/message_loop_proxy.h"
12 #include "base/sequenced_task_runner.h"
13 #include "chrome/browser/policy/async_policy_loader.h"
14 #include "components/policy/core/common/policy_bundle.h"
15 #include "components/policy/core/common/schema_registry.h"
16
17 namespace policy {
18
19 AsyncPolicyProvider::AsyncPolicyProvider(
20 SchemaRegistry* registry,
21 scoped_ptr<AsyncPolicyLoader> loader)
22 : loader_(loader.release()),
23 weak_factory_(this) {
24 // Make an immediate synchronous load on startup.
25 OnLoaderReloaded(loader_->InitialLoad(registry->schema_map()));
26 }
27
28 AsyncPolicyProvider::~AsyncPolicyProvider() {
29 DCHECK(CalledOnValidThread());
30 // Shutdown() must have been called before.
31 DCHECK(!loader_);
32 }
33
34 void AsyncPolicyProvider::Init(SchemaRegistry* registry) {
35 DCHECK(CalledOnValidThread());
36 ConfigurationPolicyProvider::Init(registry);
37
38 if (!loader_)
39 return;
40
41 AsyncPolicyLoader::UpdateCallback callback =
42 base::Bind(&AsyncPolicyProvider::LoaderUpdateCallback,
43 base::MessageLoopProxy::current(),
44 weak_factory_.GetWeakPtr());
45 bool post = loader_->task_runner()->PostTask(
46 FROM_HERE,
47 base::Bind(&AsyncPolicyLoader::Init,
48 base::Unretained(loader_),
49 callback));
50 DCHECK(post) << "AsyncPolicyProvider::Init() called with threads not running";
51 }
52
53 void AsyncPolicyProvider::Shutdown() {
54 DCHECK(CalledOnValidThread());
55 // Note on the lifetime of |loader_|:
56 // The |loader_| lives on the background thread, and is deleted from here.
57 // This means that posting tasks on the |loader_| to the background thread
58 // from the AsyncPolicyProvider is always safe, since a potential DeleteSoon()
59 // is only posted from here. The |loader_| posts back to the
60 // AsyncPolicyProvider through the |update_callback_|, which has a WeakPtr to
61 // |this|.
62 if (!loader_->task_runner()->DeleteSoon(FROM_HERE, loader_)) {
63 // The background thread doesn't exist; this only happens on unit tests.
64 delete loader_;
65 }
66 loader_ = NULL;
67 ConfigurationPolicyProvider::Shutdown();
68 }
69
70 void AsyncPolicyProvider::RefreshPolicies() {
71 DCHECK(CalledOnValidThread());
72
73 // Subtle: RefreshPolicies() has a contract that requires the next policy
74 // update notification (triggered from UpdatePolicy()) to reflect any changes
75 // made before this call. So if a caller has modified the policy settings and
76 // invoked RefreshPolicies(), then by the next notification these policies
77 // should already be provided.
78 // However, it's also possible that an asynchronous Reload() is in progress
79 // and just posted OnLoaderReloaded(). Therefore a task is posted to the
80 // background thread before posting the next Reload, to prevent a potential
81 // concurrent Reload() from triggering a notification too early. If another
82 // refresh task has been posted, it is invalidated now.
83 if (!loader_)
84 return;
85 refresh_callback_.Reset(
86 base::Bind(&AsyncPolicyProvider::ReloadAfterRefreshSync,
87 weak_factory_.GetWeakPtr()));
88 loader_->task_runner()->PostTaskAndReply(
89 FROM_HERE,
90 base::Bind(base::DoNothing),
91 refresh_callback_.callback());
92 }
93
94 void AsyncPolicyProvider::ReloadAfterRefreshSync() {
95 DCHECK(CalledOnValidThread());
96 // This task can only enter if it was posted from RefreshPolicies(), and it
97 // hasn't been cancelled meanwhile by another call to RefreshPolicies().
98 DCHECK(!refresh_callback_.IsCancelled());
99 // There can't be another refresh callback pending now, since its creation
100 // in RefreshPolicies() would have cancelled the current execution. So it's
101 // safe to cancel the |refresh_callback_| now, so that OnLoaderReloaded()
102 // sees that there is no refresh pending.
103 refresh_callback_.Cancel();
104
105 if (!loader_)
106 return;
107
108 loader_->task_runner()->PostTask(
109 FROM_HERE,
110 base::Bind(&AsyncPolicyLoader::RefreshPolicies,
111 base::Unretained(loader_),
112 schema_map()));
113 }
114
115 void AsyncPolicyProvider::OnLoaderReloaded(scoped_ptr<PolicyBundle> bundle) {
116 DCHECK(CalledOnValidThread());
117 // Only propagate policy updates if there are no pending refreshes, and if
118 // Shutdown() hasn't been called yet.
119 if (refresh_callback_.IsCancelled() && loader_)
120 UpdatePolicy(bundle.Pass());
121 }
122
123 // static
124 void AsyncPolicyProvider::LoaderUpdateCallback(
125 scoped_refptr<base::MessageLoopProxy> loop,
126 base::WeakPtr<AsyncPolicyProvider> weak_this,
127 scoped_ptr<PolicyBundle> bundle) {
128 loop->PostTask(FROM_HERE,
129 base::Bind(&AsyncPolicyProvider::OnLoaderReloaded,
130 weak_this,
131 base::Passed(&bundle)));
132 }
133
134 } // namespace policy
OLDNEW
« no previous file with comments | « chrome/browser/policy/async_policy_provider.h ('k') | chrome/browser/policy/async_policy_provider_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698