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

Side by Side Diff: remoting/host/policy_hack/nat_policy.cc

Issue 10804040: [Chromoting] Refactor the host policy watcher so that policies can easily be added. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Pass the policy dictionary as a scoped_ptr. Created 8 years, 5 months 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
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 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 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 // Most of this code is copied from: 5 // Most of this code is copied from:
6 // src/chrome/browser/policy/asynchronous_policy_loader.{h,cc} 6 // src/chrome/browser/policy/asynchronous_policy_loader.{h,cc}
7 7
8 #include "remoting/host/policy_hack/nat_policy.h" 8 #include "remoting/host/policy_hack/nat_policy.h"
9 9
10 #include "base/bind.h" 10 #include "base/bind.h"
11 #include "base/compiler_specific.h" 11 #include "base/compiler_specific.h"
12 #include "base/location.h" 12 #include "base/location.h"
13 #include "base/memory/weak_ptr.h" 13 #include "base/memory/weak_ptr.h"
14 #include "base/single_thread_task_runner.h" 14 #include "base/single_thread_task_runner.h"
15 #include "base/synchronization/waitable_event.h" 15 #include "base/synchronization/waitable_event.h"
16 #include "base/time.h" 16 #include "base/time.h"
17 #include "base/values.h" 17 #include "base/values.h"
18 18
19 namespace remoting { 19 namespace remoting {
20 namespace policy_hack { 20 namespace policy_hack {
21 21
22 namespace { 22 namespace {
23 // The time interval for rechecking policy. This is our fallback in case the 23 // The time interval for rechecking policy. This is our fallback in case the
24 // delegate never reports a change to the ReloadObserver. 24 // delegate never reports a change to the ReloadObserver.
25 const int kFallbackReloadDelayMinutes = 15; 25 const int kFallbackReloadDelayMinutes = 15;
26 26
27 // Gets a boolean from a dictionary, or returns a default value if the boolean
28 // couldn't be read.
29 bool GetBooleanOrDefault(const base::DictionaryValue* dict, const char* key,
30 bool default_if_value_missing,
31 bool default_if_value_not_boolean) {
32 if (!dict->HasKey(key)) {
33 return default_if_value_missing;
34 }
35 base::Value* value;
36 if (dict->Get(key, &value) && value->IsType(base::Value::TYPE_BOOLEAN)) {
37 bool bool_value;
38 CHECK(value->GetAsBoolean(&bool_value));
39 return bool_value;
40 }
41 return default_if_value_not_boolean;
42 }
43
44 // Copies a boolean from one dictionary to another, using a default value
45 // if the boolean couldn't be read from the first dictionary.
46 void CopyBooleanOrDefault(base::DictionaryValue* to,
47 const base::DictionaryValue* from, const char* key,
48 bool default_if_value_missing,
49 bool default_if_value_not_boolean) {
50 to->Set(key, base::Value::CreateBooleanValue(
51 GetBooleanOrDefault(from, key, default_if_value_missing,
52 default_if_value_not_boolean)));
53 }
54
55 // Copies all policy values from one dictionary to another, using default values
56 // when necessary.
57 scoped_ptr<base::DictionaryValue> AddDefaultValuesWhenNecessary(
58 const base::DictionaryValue* from) {
59 scoped_ptr<base::DictionaryValue> to(new base::DictionaryValue());
60 CopyBooleanOrDefault(to.get(), from,
61 PolicyWatcher::kNatPolicyName, true, false);
62 return to.Pass();
63 }
64
27 } // namespace 65 } // namespace
28 66
29 const char NatPolicy::kNatPolicyName[] = "RemoteAccessHostFirewallTraversal"; 67 const char PolicyWatcher::kNatPolicyName[] =
68 "RemoteAccessHostFirewallTraversal";
30 69
31 NatPolicy::NatPolicy(scoped_refptr<base::SingleThreadTaskRunner> task_runner) 70 const char* const PolicyWatcher::kBooleanPolicyNames[] =
garykac 2012/07/23 17:29:26 We'll have boolean, string and int policy types th
simonmorris 2012/07/23 19:34:55 The next CL will have a different policy type, so
71 { PolicyWatcher::kNatPolicyName };
72
73 const int PolicyWatcher::kBooleanPolicyNamesNum =
74 arraysize(kBooleanPolicyNames);
75
76 PolicyWatcher::PolicyWatcher(
77 scoped_refptr<base::SingleThreadTaskRunner> task_runner)
32 : task_runner_(task_runner), 78 : task_runner_(task_runner),
33 current_nat_enabled_state_(false), 79 old_policies_(new base::DictionaryValue()),
34 first_state_published_(false),
35 ALLOW_THIS_IN_INITIALIZER_LIST(weak_factory_(this)) { 80 ALLOW_THIS_IN_INITIALIZER_LIST(weak_factory_(this)) {
36 } 81 }
37 82
38 NatPolicy::~NatPolicy() { 83 PolicyWatcher::~PolicyWatcher() {
39 } 84 }
40 85
41 void NatPolicy::StartWatching(const NatEnabledCallback& nat_enabled_cb) { 86 void PolicyWatcher::StartWatching(const PolicyCallback& policy_callback) {
42 if (!OnPolicyThread()) { 87 if (!OnPolicyWatcherThread()) {
43 task_runner_->PostTask(FROM_HERE, 88 task_runner_->PostTask(FROM_HERE,
44 base::Bind(&NatPolicy::StartWatching, 89 base::Bind(&PolicyWatcher::StartWatching,
45 base::Unretained(this), 90 base::Unretained(this),
46 nat_enabled_cb)); 91 policy_callback));
47 return; 92 return;
48 } 93 }
49 94
50 nat_enabled_cb_ = nat_enabled_cb; 95 policy_callback_ = policy_callback;
51 StartWatchingInternal(); 96 StartWatchingInternal();
52 } 97 }
53 98
54 void NatPolicy::StopWatching(base::WaitableEvent* done) { 99 void PolicyWatcher::StopWatching(base::WaitableEvent* done) {
55 if (!OnPolicyThread()) { 100 if (!OnPolicyWatcherThread()) {
56 task_runner_->PostTask(FROM_HERE, 101 task_runner_->PostTask(FROM_HERE,
57 base::Bind(&NatPolicy::StopWatching, 102 base::Bind(&PolicyWatcher::StopWatching,
58 base::Unretained(this), done)); 103 base::Unretained(this), done));
59 return; 104 return;
60 } 105 }
61 106
62 StopWatchingInternal(); 107 StopWatchingInternal();
63 weak_factory_.InvalidateWeakPtrs(); 108 weak_factory_.InvalidateWeakPtrs();
64 nat_enabled_cb_.Reset(); 109 policy_callback_.Reset();
65 110
66 done->Signal(); 111 done->Signal();
67 } 112 }
68 113
69 void NatPolicy::ScheduleFallbackReloadTask() { 114 void PolicyWatcher::ScheduleFallbackReloadTask() {
70 DCHECK(OnPolicyThread()); 115 DCHECK(OnPolicyWatcherThread());
71 ScheduleReloadTask( 116 ScheduleReloadTask(
72 base::TimeDelta::FromMinutes(kFallbackReloadDelayMinutes)); 117 base::TimeDelta::FromMinutes(kFallbackReloadDelayMinutes));
73 } 118 }
74 119
75 void NatPolicy::ScheduleReloadTask(const base::TimeDelta& delay) { 120 void PolicyWatcher::ScheduleReloadTask(const base::TimeDelta& delay) {
76 DCHECK(OnPolicyThread()); 121 DCHECK(OnPolicyWatcherThread());
77 task_runner_->PostDelayedTask( 122 task_runner_->PostDelayedTask(
78 FROM_HERE, 123 FROM_HERE,
79 base::Bind(&NatPolicy::Reload, weak_factory_.GetWeakPtr()), 124 base::Bind(&PolicyWatcher::Reload, weak_factory_.GetWeakPtr()),
80 delay); 125 delay);
81 } 126 }
82 127
83 bool NatPolicy::OnPolicyThread() const { 128 bool PolicyWatcher::OnPolicyWatcherThread() const {
84 return task_runner_->BelongsToCurrentThread(); 129 return task_runner_->BelongsToCurrentThread();
85 } 130 }
86 131
87 void NatPolicy::UpdateNatPolicy(base::DictionaryValue* new_policy) { 132 void PolicyWatcher::UpdatePolicies(
88 DCHECK(OnPolicyThread()); 133 const base::DictionaryValue* new_policies_raw) {
89 bool new_nat_enabled_state = false; 134 DCHECK(OnPolicyWatcherThread());
90 if (!new_policy->HasKey(kNatPolicyName)) { 135
91 // If unspecified, the default value of this policy is true. 136 // Use default values for any missing policies.
92 new_nat_enabled_state = true; 137 scoped_ptr<base::DictionaryValue> new_policies =
93 } else { 138 AddDefaultValuesWhenNecessary(new_policies_raw);
94 // Otherwise, try to parse the value and only change from false if we get 139
95 // a successful read. 140 // Find the changed policies.
96 base::Value* value; 141 scoped_ptr<base::DictionaryValue> changed_policies(
97 if (new_policy->Get(kNatPolicyName, &value) && 142 new base::DictionaryValue());
98 value->IsType(base::Value::TYPE_BOOLEAN)) { 143 base::DictionaryValue::Iterator iter(*new_policies);
99 CHECK(value->GetAsBoolean(&new_nat_enabled_state)); 144 while (iter.HasNext()) {
145 base::Value* old_policy;
146 if (!(old_policies_->Get(iter.key(), &old_policy) &&
147 old_policy->Equals(&iter.value()))) {
148 changed_policies->Set(iter.key(), iter.value().DeepCopy());
100 } 149 }
150 iter.Advance();
101 } 151 }
102 152
103 if (!first_state_published_ || 153 // Save the new policies.
104 (new_nat_enabled_state != current_nat_enabled_state_)) { 154 old_policies_.swap(new_policies);
105 first_state_published_ = true; 155
106 current_nat_enabled_state_ = new_nat_enabled_state; 156 // Notify our client of the changed policies.
107 nat_enabled_cb_.Run(current_nat_enabled_state_); 157 if (!changed_policies->empty()) {
158 policy_callback_.Run(changed_policies.Pass());
108 } 159 }
109 } 160 }
110 161
111 } // namespace policy_hack 162 } // namespace policy_hack
112 } // namespace remoting 163 } // namespace remoting
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698