[Chromoting] Refactor the host policy watcher so that policies can easily be added.
This CL renames some classes, but not the source files, to make it easier to
compare the old and new versions. A follow-up CL will rename the files.
BUG=137906
Review URL: https://chromiumcodereview.appspot.com/10804040
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@148029 0039d316-1c4b-4281-b951-d872f2087c98
diff --git a/remoting/host/plugin/host_script_object.cc b/remoting/host/plugin/host_script_object.cc
index 1892f07..a8d7b0c 100644
--- a/remoting/host/plugin/host_script_object.cc
+++ b/remoting/host/plugin/host_script_object.cc
@@ -26,7 +26,7 @@
#include "remoting/host/pin_hash.h"
#include "remoting/host/plugin/daemon_controller.h"
#include "remoting/host/plugin/host_log_handler.h"
-#include "remoting/host/policy_hack/nat_policy.h"
+#include "remoting/host/policy_hack/policy_watcher.h"
#include "remoting/host/register_support_host_request.h"
#include "remoting/host/session_manager_factory.h"
#include "remoting/jingle_glue/xmpp_signal_strategy.h"
@@ -104,11 +104,11 @@
plugin_task_runner_->Detach();
// Stop listening for policy updates.
- if (nat_policy_.get()) {
- base::WaitableEvent nat_policy_stopped_(true, false);
- nat_policy_->StopWatching(&nat_policy_stopped_);
- nat_policy_stopped_.Wait();
- nat_policy_.reset();
+ if (policy_watcher_.get()) {
+ base::WaitableEvent policy_watcher_stopped_(true, false);
+ policy_watcher_->StopWatching(&policy_watcher_stopped_);
+ policy_watcher_stopped_.Wait();
+ policy_watcher_.reset();
}
if (host_context_.get()) {
@@ -144,10 +144,10 @@
return false;
}
- nat_policy_.reset(
- policy_hack::NatPolicy::Create(host_context_->network_task_runner()));
- nat_policy_->StartWatching(
- base::Bind(&HostNPScriptObject::OnNatPolicyUpdate,
+ policy_watcher_.reset(
+ policy_hack::PolicyWatcher::Create(host_context_->network_task_runner()));
+ policy_watcher_->StartWatching(
+ base::Bind(&HostNPScriptObject::OnPolicyUpdate,
base::Unretained(this)));
return true;
}
@@ -891,6 +891,23 @@
disconnected_event_.Signal();
}
+void HostNPScriptObject::OnPolicyUpdate(
+ scoped_ptr<base::DictionaryValue> policies) {
+ if (!host_context_->network_task_runner()->BelongsToCurrentThread()) {
+ host_context_->network_task_runner()->PostTask(
+ FROM_HERE,
+ base::Bind(&HostNPScriptObject::OnPolicyUpdate,
+ base::Unretained(this), base::Passed(&policies)));
+ return;
+ }
+
+ bool bool_value;
+ if (policies->GetBoolean(policy_hack::PolicyWatcher::kNatPolicyName,
+ &bool_value)) {
+ OnNatPolicyUpdate(bool_value);
+ }
+}
+
void HostNPScriptObject::OnNatPolicyUpdate(bool nat_traversal_enabled) {
if (!host_context_->network_task_runner()->BelongsToCurrentThread()) {
host_context_->network_task_runner()->PostTask(
diff --git a/remoting/host/plugin/host_script_object.h b/remoting/host/plugin/host_script_object.h
index 45237d14..9b9280b0 100644
--- a/remoting/host/plugin/host_script_object.h
+++ b/remoting/host/plugin/host_script_object.h
@@ -41,7 +41,7 @@
class SupportAccessVerifier;
namespace policy_hack {
-class NatPolicy;
+class PolicyWatcher;
} // namespace policy_hack
// NPAPI plugin implementation for remoting host script object.
@@ -208,6 +208,9 @@
// Callback for ChromotingHost::Shutdown().
void OnShutdownFinished();
+ // Called when a policy is updated.
+ void OnPolicyUpdate(scoped_ptr<base::DictionaryValue> policies);
+
// Called when the nat traversal policy is updated.
void OnNatPolicyUpdate(bool nat_traversal_enabled);
@@ -319,7 +322,7 @@
base::Lock nat_policy_lock_;
- scoped_ptr<policy_hack::NatPolicy> nat_policy_;
+ scoped_ptr<policy_hack::PolicyWatcher> policy_watcher_;
// Host the current nat traversal policy setting.
bool nat_traversal_enabled_;
diff --git a/remoting/host/policy_hack/fake_policy_watcher.cc b/remoting/host/policy_hack/fake_policy_watcher.cc
new file mode 100644
index 0000000..809961b2
--- /dev/null
+++ b/remoting/host/policy_hack/fake_policy_watcher.cc
@@ -0,0 +1,34 @@
+// Copyright (c) 2012 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "remoting/host/policy_hack/fake_policy_watcher.h"
+
+#include "base/single_thread_task_runner.h"
+
+namespace remoting {
+namespace policy_hack {
+
+FakePolicyWatcher::FakePolicyWatcher(
+ scoped_refptr<base::SingleThreadTaskRunner> task_runner)
+ : PolicyWatcher(task_runner) {
+}
+
+FakePolicyWatcher::~FakePolicyWatcher() {
+}
+
+void FakePolicyWatcher::SetPolicies(const base::DictionaryValue* policies) {
+ UpdatePolicies(policies);
+}
+
+void FakePolicyWatcher::StartWatchingInternal() {
+}
+
+void FakePolicyWatcher::StopWatchingInternal() {
+}
+
+void FakePolicyWatcher::Reload() {
+}
+
+} // namespace policy_hack
+} // namespace remoting
diff --git a/remoting/host/policy_hack/fake_policy_watcher.h b/remoting/host/policy_hack/fake_policy_watcher.h
new file mode 100644
index 0000000..baec95926
--- /dev/null
+++ b/remoting/host/policy_hack/fake_policy_watcher.h
@@ -0,0 +1,30 @@
+// Copyright (c) 2012 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef REMOTING_HOST_POLICY_HACK_FAKE_POLICY_WATCHER_H_
+#define REMOTING_HOST_POLICY_HACK_FAKE_POLICY_WATCHER_H_
+
+#include "remoting/host/policy_hack/policy_watcher.h"
+
+namespace remoting {
+namespace policy_hack {
+
+class FakePolicyWatcher : public PolicyWatcher {
+ public:
+ explicit FakePolicyWatcher(
+ scoped_refptr<base::SingleThreadTaskRunner> task_runner);
+ virtual ~FakePolicyWatcher();
+
+ void SetPolicies(const base::DictionaryValue* policies);
+
+ protected:
+ virtual void StartWatchingInternal() OVERRIDE;
+ virtual void StopWatchingInternal() OVERRIDE;
+ virtual void Reload() OVERRIDE;
+};
+
+} // namespace policy_hack
+} // namespace remoting
+
+#endif // REMOTING_HOST_POLICY_HACK_FAKE_POLICY_WATCHER_H_
diff --git a/remoting/host/policy_hack/mock_policy_callback.cc b/remoting/host/policy_hack/mock_policy_callback.cc
new file mode 100644
index 0000000..a069b88
--- /dev/null
+++ b/remoting/host/policy_hack/mock_policy_callback.cc
@@ -0,0 +1,22 @@
+// Copyright (c) 2012 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "remoting/host/policy_hack/mock_policy_callback.h"
+
+namespace remoting {
+namespace policy_hack {
+
+MockPolicyCallback::MockPolicyCallback() {
+}
+
+MockPolicyCallback::~MockPolicyCallback() {
+}
+
+void MockPolicyCallback::OnPolicyUpdate(
+ scoped_ptr<base::DictionaryValue> policies) {
+ OnPolicyUpdatePtr(policies.get());
+}
+
+} // namespace policy_hack
+} // namespace remoting
diff --git a/remoting/host/policy_hack/mock_policy_callback.h b/remoting/host/policy_hack/mock_policy_callback.h
new file mode 100644
index 0000000..2ae9b0d
--- /dev/null
+++ b/remoting/host/policy_hack/mock_policy_callback.h
@@ -0,0 +1,31 @@
+// Copyright (c) 2012 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef REMOTING_HOST_POLICY_HACK_MOCK_POLICY_CALLBACK_H_
+#define REMOTING_HOST_POLICY_HACK_MOCK_POLICY_CALLBACK_H_
+
+#include "base/basictypes.h"
+#include "base/memory/scoped_ptr.h"
+#include "base/values.h"
+#include "testing/gmock/include/gmock/gmock.h"
+
+namespace remoting {
+namespace policy_hack {
+
+class MockPolicyCallback {
+ public:
+ MockPolicyCallback();
+ virtual ~MockPolicyCallback();
+
+ MOCK_METHOD1(OnPolicyUpdatePtr, void(const base::DictionaryValue* policies));
+ void OnPolicyUpdate(scoped_ptr<base::DictionaryValue> policies);
+
+ private:
+ DISALLOW_COPY_AND_ASSIGN(MockPolicyCallback);
+};
+
+} // namespace policy_hack
+} // namespace remoting
+
+#endif // REMOTING_HOST_POLICY_HACK_MOCK_POLICY_CALLBACK_H_
diff --git a/remoting/host/policy_hack/nat_policy.cc b/remoting/host/policy_hack/nat_policy.cc
deleted file mode 100644
index 77f376a..0000000
--- a/remoting/host/policy_hack/nat_policy.cc
+++ /dev/null
@@ -1,112 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-// Most of this code is copied from:
-// src/chrome/browser/policy/asynchronous_policy_loader.{h,cc}
-
-#include "remoting/host/policy_hack/nat_policy.h"
-
-#include "base/bind.h"
-#include "base/compiler_specific.h"
-#include "base/location.h"
-#include "base/memory/weak_ptr.h"
-#include "base/single_thread_task_runner.h"
-#include "base/synchronization/waitable_event.h"
-#include "base/time.h"
-#include "base/values.h"
-
-namespace remoting {
-namespace policy_hack {
-
-namespace {
-// The time interval for rechecking policy. This is our fallback in case the
-// delegate never reports a change to the ReloadObserver.
-const int kFallbackReloadDelayMinutes = 15;
-
-} // namespace
-
-const char NatPolicy::kNatPolicyName[] = "RemoteAccessHostFirewallTraversal";
-
-NatPolicy::NatPolicy(scoped_refptr<base::SingleThreadTaskRunner> task_runner)
- : task_runner_(task_runner),
- current_nat_enabled_state_(false),
- first_state_published_(false),
- ALLOW_THIS_IN_INITIALIZER_LIST(weak_factory_(this)) {
-}
-
-NatPolicy::~NatPolicy() {
-}
-
-void NatPolicy::StartWatching(const NatEnabledCallback& nat_enabled_cb) {
- if (!OnPolicyThread()) {
- task_runner_->PostTask(FROM_HERE,
- base::Bind(&NatPolicy::StartWatching,
- base::Unretained(this),
- nat_enabled_cb));
- return;
- }
-
- nat_enabled_cb_ = nat_enabled_cb;
- StartWatchingInternal();
-}
-
-void NatPolicy::StopWatching(base::WaitableEvent* done) {
- if (!OnPolicyThread()) {
- task_runner_->PostTask(FROM_HERE,
- base::Bind(&NatPolicy::StopWatching,
- base::Unretained(this), done));
- return;
- }
-
- StopWatchingInternal();
- weak_factory_.InvalidateWeakPtrs();
- nat_enabled_cb_.Reset();
-
- done->Signal();
-}
-
-void NatPolicy::ScheduleFallbackReloadTask() {
- DCHECK(OnPolicyThread());
- ScheduleReloadTask(
- base::TimeDelta::FromMinutes(kFallbackReloadDelayMinutes));
-}
-
-void NatPolicy::ScheduleReloadTask(const base::TimeDelta& delay) {
- DCHECK(OnPolicyThread());
- task_runner_->PostDelayedTask(
- FROM_HERE,
- base::Bind(&NatPolicy::Reload, weak_factory_.GetWeakPtr()),
- delay);
-}
-
-bool NatPolicy::OnPolicyThread() const {
- return task_runner_->BelongsToCurrentThread();
-}
-
-void NatPolicy::UpdateNatPolicy(base::DictionaryValue* new_policy) {
- DCHECK(OnPolicyThread());
- bool new_nat_enabled_state = false;
- if (!new_policy->HasKey(kNatPolicyName)) {
- // If unspecified, the default value of this policy is true.
- new_nat_enabled_state = true;
- } else {
- // Otherwise, try to parse the value and only change from false if we get
- // a successful read.
- base::Value* value;
- if (new_policy->Get(kNatPolicyName, &value) &&
- value->IsType(base::Value::TYPE_BOOLEAN)) {
- CHECK(value->GetAsBoolean(&new_nat_enabled_state));
- }
- }
-
- if (!first_state_published_ ||
- (new_nat_enabled_state != current_nat_enabled_state_)) {
- first_state_published_ = true;
- current_nat_enabled_state_ = new_nat_enabled_state;
- nat_enabled_cb_.Run(current_nat_enabled_state_);
- }
-}
-
-} // namespace policy_hack
-} // namespace remoting
diff --git a/remoting/host/policy_hack/nat_policy.h b/remoting/host/policy_hack/nat_policy.h
deleted file mode 100644
index 93f1c41..0000000
--- a/remoting/host/policy_hack/nat_policy.h
+++ /dev/null
@@ -1,79 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef REMOTING_HOST_POLICY_HACK_NAT_POLICY_H_
-#define REMOTING_HOST_POLICY_HACK_NAT_POLICY_H_
-
-#include "base/callback.h"
-#include "base/memory/weak_ptr.h"
-
-namespace base {
-class DictionaryValue;
-class SingleThreadTaskRunner;
-class TimeDelta;
-class WaitableEvent;
-} // namespace base
-
-namespace remoting {
-namespace policy_hack {
-
-// Watches for changes to the managed remote access host NAT policies.
-// If StartWatching() has been called, then before this object can be deleted,
-// StopWatching() have completed (the provided |done| event must be signaled).
-class NatPolicy {
- public:
- // Called with the current status of whether or not NAT traversal is enabled.
- typedef base::Callback<void(bool)> NatEnabledCallback;
-
- explicit NatPolicy(scoped_refptr<base::SingleThreadTaskRunner> task_runner);
- virtual ~NatPolicy();
-
- // This guarantees that the |nat_enabled_cb| is called at least once with
- // the current policy. After that, |nat_enabled_cb| will be called whenever
- // a change to the nat policy is detected.
- virtual void StartWatching(const NatEnabledCallback& nat_enabled_cb);
-
- // Should be called after StartWatching() before the object is deleted. Calls
- // just wait for |done| to be signaled before deleting the object.
- virtual void StopWatching(base::WaitableEvent* done);
-
- // Implemented by each platform. This message loop should be an IO message
- // loop.
- static NatPolicy* Create(
- scoped_refptr<base::SingleThreadTaskRunner> task_runner);
-
- protected:
- virtual void StartWatchingInternal() = 0;
- virtual void StopWatchingInternal() = 0;
- virtual void Reload() = 0;
-
- // Used to check if the class is on the right thread.
- bool OnPolicyThread() const;
-
- // Takes the policy dictionary from the OS specific store and extracts the
- // NAT traversal setting.
- void UpdateNatPolicy(base::DictionaryValue* new_policy);
-
- // Used for time-based reloads in case something goes wrong with the
- // notification system.
- void ScheduleFallbackReloadTask();
- void ScheduleReloadTask(const base::TimeDelta& delay);
-
- static const char kNatPolicyName[];
-
- private:
- scoped_refptr<base::SingleThreadTaskRunner> task_runner_;
-
- NatEnabledCallback nat_enabled_cb_;
- bool current_nat_enabled_state_;
- bool first_state_published_;
-
- // Allows us to cancel any inflight FileWatcher events or scheduled reloads.
- base::WeakPtrFactory<NatPolicy> weak_factory_;
-};
-
-} // namespace policy_hack
-} // namespace remoting
-
-#endif // REMOTING_HOST_POLICY_HACK_NAT_POLICY_H_
diff --git a/remoting/host/policy_hack/policy_watcher.cc b/remoting/host/policy_hack/policy_watcher.cc
new file mode 100644
index 0000000..23320ea
--- /dev/null
+++ b/remoting/host/policy_hack/policy_watcher.cc
@@ -0,0 +1,163 @@
+// Copyright (c) 2012 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Most of this code is copied from:
+// src/chrome/browser/policy/asynchronous_policy_loader.{h,cc}
+
+#include "remoting/host/policy_hack/policy_watcher.h"
+
+#include "base/bind.h"
+#include "base/compiler_specific.h"
+#include "base/location.h"
+#include "base/memory/weak_ptr.h"
+#include "base/single_thread_task_runner.h"
+#include "base/synchronization/waitable_event.h"
+#include "base/time.h"
+#include "base/values.h"
+
+namespace remoting {
+namespace policy_hack {
+
+namespace {
+// The time interval for rechecking policy. This is our fallback in case the
+// delegate never reports a change to the ReloadObserver.
+const int kFallbackReloadDelayMinutes = 15;
+
+// Gets a boolean from a dictionary, or returns a default value if the boolean
+// couldn't be read.
+bool GetBooleanOrDefault(const base::DictionaryValue* dict, const char* key,
+ bool default_if_value_missing,
+ bool default_if_value_not_boolean) {
+ if (!dict->HasKey(key)) {
+ return default_if_value_missing;
+ }
+ base::Value* value;
+ if (dict->Get(key, &value) && value->IsType(base::Value::TYPE_BOOLEAN)) {
+ bool bool_value;
+ CHECK(value->GetAsBoolean(&bool_value));
+ return bool_value;
+ }
+ return default_if_value_not_boolean;
+}
+
+// Copies a boolean from one dictionary to another, using a default value
+// if the boolean couldn't be read from the first dictionary.
+void CopyBooleanOrDefault(base::DictionaryValue* to,
+ const base::DictionaryValue* from, const char* key,
+ bool default_if_value_missing,
+ bool default_if_value_not_boolean) {
+ to->Set(key, base::Value::CreateBooleanValue(
+ GetBooleanOrDefault(from, key, default_if_value_missing,
+ default_if_value_not_boolean)));
+}
+
+// Copies all policy values from one dictionary to another, using default values
+// when necessary.
+scoped_ptr<base::DictionaryValue> AddDefaultValuesWhenNecessary(
+ const base::DictionaryValue* from) {
+ scoped_ptr<base::DictionaryValue> to(new base::DictionaryValue());
+ CopyBooleanOrDefault(to.get(), from,
+ PolicyWatcher::kNatPolicyName, true, false);
+ return to.Pass();
+}
+
+} // namespace
+
+const char PolicyWatcher::kNatPolicyName[] =
+ "RemoteAccessHostFirewallTraversal";
+
+const char* const PolicyWatcher::kBooleanPolicyNames[] =
+ { PolicyWatcher::kNatPolicyName };
+
+const int PolicyWatcher::kBooleanPolicyNamesNum =
+ arraysize(kBooleanPolicyNames);
+
+PolicyWatcher::PolicyWatcher(
+ scoped_refptr<base::SingleThreadTaskRunner> task_runner)
+ : task_runner_(task_runner),
+ old_policies_(new base::DictionaryValue()),
+ ALLOW_THIS_IN_INITIALIZER_LIST(weak_factory_(this)) {
+}
+
+PolicyWatcher::~PolicyWatcher() {
+}
+
+void PolicyWatcher::StartWatching(const PolicyCallback& policy_callback) {
+ if (!OnPolicyWatcherThread()) {
+ task_runner_->PostTask(FROM_HERE,
+ base::Bind(&PolicyWatcher::StartWatching,
+ base::Unretained(this),
+ policy_callback));
+ return;
+ }
+
+ policy_callback_ = policy_callback;
+ StartWatchingInternal();
+}
+
+void PolicyWatcher::StopWatching(base::WaitableEvent* done) {
+ if (!OnPolicyWatcherThread()) {
+ task_runner_->PostTask(FROM_HERE,
+ base::Bind(&PolicyWatcher::StopWatching,
+ base::Unretained(this), done));
+ return;
+ }
+
+ StopWatchingInternal();
+ weak_factory_.InvalidateWeakPtrs();
+ policy_callback_.Reset();
+
+ done->Signal();
+}
+
+void PolicyWatcher::ScheduleFallbackReloadTask() {
+ DCHECK(OnPolicyWatcherThread());
+ ScheduleReloadTask(
+ base::TimeDelta::FromMinutes(kFallbackReloadDelayMinutes));
+}
+
+void PolicyWatcher::ScheduleReloadTask(const base::TimeDelta& delay) {
+ DCHECK(OnPolicyWatcherThread());
+ task_runner_->PostDelayedTask(
+ FROM_HERE,
+ base::Bind(&PolicyWatcher::Reload, weak_factory_.GetWeakPtr()),
+ delay);
+}
+
+bool PolicyWatcher::OnPolicyWatcherThread() const {
+ return task_runner_->BelongsToCurrentThread();
+}
+
+void PolicyWatcher::UpdatePolicies(
+ const base::DictionaryValue* new_policies_raw) {
+ DCHECK(OnPolicyWatcherThread());
+
+ // Use default values for any missing policies.
+ scoped_ptr<base::DictionaryValue> new_policies =
+ AddDefaultValuesWhenNecessary(new_policies_raw);
+
+ // Find the changed policies.
+ scoped_ptr<base::DictionaryValue> changed_policies(
+ new base::DictionaryValue());
+ base::DictionaryValue::Iterator iter(*new_policies);
+ while (iter.HasNext()) {
+ base::Value* old_policy;
+ if (!(old_policies_->Get(iter.key(), &old_policy) &&
+ old_policy->Equals(&iter.value()))) {
+ changed_policies->Set(iter.key(), iter.value().DeepCopy());
+ }
+ iter.Advance();
+ }
+
+ // Save the new policies.
+ old_policies_.swap(new_policies);
+
+ // Notify our client of the changed policies.
+ if (!changed_policies->empty()) {
+ policy_callback_.Run(changed_policies.Pass());
+ }
+}
+
+} // namespace policy_hack
+} // namespace remoting
diff --git a/remoting/host/policy_hack/policy_watcher.h b/remoting/host/policy_hack/policy_watcher.h
new file mode 100644
index 0000000..ac0a567
--- /dev/null
+++ b/remoting/host/policy_hack/policy_watcher.h
@@ -0,0 +1,87 @@
+// Copyright (c) 2012 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef REMOTING_HOST_POLICY_HACK_POLICY_WATCHER_H_
+#define REMOTING_HOST_POLICY_HACK_POLICY_WATCHER_H_
+
+#include "base/callback.h"
+#include "base/memory/weak_ptr.h"
+#include "base/values.h"
+
+namespace base {
+class SingleThreadTaskRunner;
+class TimeDelta;
+class WaitableEvent;
+} // namespace base
+
+namespace remoting {
+namespace policy_hack {
+
+// Watches for changes to the managed remote access host policies.
+// If StartWatching() has been called, then before this object can be deleted,
+// StopWatching() have completed (the provided |done| event must be signaled).
+class PolicyWatcher {
+ public:
+ // Called first with all policies, and subsequently with any changed policies.
+ typedef base::Callback<void(scoped_ptr<base::DictionaryValue>)>
+ PolicyCallback;
+
+ explicit PolicyWatcher(
+ scoped_refptr<base::SingleThreadTaskRunner> task_runner);
+ virtual ~PolicyWatcher();
+
+ // This guarantees that the |policy_callback| is called at least once with
+ // the current policies. After that, |policy_callback| will be called
+ // whenever a change to any policy is detected. It will then be called only
+ // with the changed policies.
+ virtual void StartWatching(const PolicyCallback& policy_callback);
+
+ // Should be called after StartWatching() before the object is deleted. Calls
+ // just wait for |done| to be signaled before deleting the object.
+ virtual void StopWatching(base::WaitableEvent* done);
+
+ // Implemented by each platform. This message loop should be an IO message
+ // loop.
+ static PolicyWatcher* Create(
+ scoped_refptr<base::SingleThreadTaskRunner> task_runner);
+
+ // The name of the NAT traversal policy.
+ static const char kNatPolicyName[];
+
+ protected:
+ virtual void StartWatchingInternal() = 0;
+ virtual void StopWatchingInternal() = 0;
+ virtual void Reload() = 0;
+
+ // Used to check if the class is on the right thread.
+ bool OnPolicyWatcherThread() const;
+
+ // Takes the policy dictionary from the OS specific store and extracts the
+ // relevant policies.
+ void UpdatePolicies(const base::DictionaryValue* new_policy);
+
+ // Used for time-based reloads in case something goes wrong with the
+ // notification system.
+ void ScheduleFallbackReloadTask();
+ void ScheduleReloadTask(const base::TimeDelta& delay);
+
+ // The names of policies with boolean values.
+ static const char* const kBooleanPolicyNames[];
+ static const int kBooleanPolicyNamesNum;
+
+ private:
+ scoped_refptr<base::SingleThreadTaskRunner> task_runner_;
+
+ PolicyCallback policy_callback_;
+
+ scoped_ptr<base::DictionaryValue> old_policies_;
+
+ // Allows us to cancel any inflight FileWatcher events or scheduled reloads.
+ base::WeakPtrFactory<PolicyWatcher> weak_factory_;
+};
+
+} // namespace policy_hack
+} // namespace remoting
+
+#endif // REMOTING_HOST_POLICY_HACK_POLICY_WATCHER_H_
diff --git a/remoting/host/policy_hack/nat_policy_linux.cc b/remoting/host/policy_hack/policy_watcher_linux.cc
similarity index 86%
rename from remoting/host/policy_hack/nat_policy_linux.cc
rename to remoting/host/policy_hack/policy_watcher_linux.cc
index 184d6fc..351e8e5 100644
--- a/remoting/host/policy_hack/nat_policy_linux.cc
+++ b/remoting/host/policy_hack/policy_watcher_linux.cc
@@ -12,7 +12,7 @@
#include <set>
-#include "remoting/host/policy_hack/nat_policy.h"
+#include "remoting/host/policy_hack/policy_watcher.h"
#include "base/bind.h"
#include "base/compiler_specific.h"
@@ -42,11 +42,11 @@
} // namespace
-class NatPolicyLinux : public NatPolicy {
+class PolicyWatcherLinux : public PolicyWatcher {
public:
- NatPolicyLinux(scoped_refptr<base::SingleThreadTaskRunner> task_runner,
- const FilePath& config_dir)
- : NatPolicy(task_runner),
+ PolicyWatcherLinux(scoped_refptr<base::SingleThreadTaskRunner> task_runner,
+ const FilePath& config_dir)
+ : PolicyWatcher(task_runner),
config_dir_(config_dir),
ALLOW_THIS_IN_INITIALIZER_LIST(weak_factory_(this)) {
// Detach the factory because we ensure that only the policy thread ever
@@ -57,11 +57,11 @@
weak_factory_.DetachFromThread();
}
- virtual ~NatPolicyLinux() {}
+ virtual ~PolicyWatcherLinux() {}
protected:
virtual void StartWatchingInternal() OVERRIDE {
- DCHECK(OnPolicyThread());
+ DCHECK(OnPolicyWatcherThread());
watcher_.reset(new base::files::FilePathWatcher());
if (!config_dir_.empty() &&
@@ -80,30 +80,30 @@
}
virtual void StopWatchingInternal() OVERRIDE {
- DCHECK(OnPolicyThread());
+ DCHECK(OnPolicyWatcherThread());
// Cancel any inflight requests.
watcher_.reset();
}
// Called by FilePathWatcherDelegate.
virtual void OnFilePathError(const FilePath& path) {
- LOG(ERROR) << "NatPolicyLinux on " << path.value()
+ LOG(ERROR) << "PolicyWatcherLinux on " << path.value()
<< " failed.";
}
// Called by FilePathWatcherDelegate.
virtual void OnFilePathChanged(const FilePath& path) {
- DCHECK(OnPolicyThread());
+ DCHECK(OnPolicyWatcherThread());
Reload();
}
private:
- // Needed to avoid refcounting NatPolicyLinux.
+ // Needed to avoid refcounting PolicyWatcherLinux.
class FilePathWatcherDelegate :
public base::files::FilePathWatcher::Delegate {
public:
- FilePathWatcherDelegate(base::WeakPtr<NatPolicyLinux> policy_watcher)
+ FilePathWatcherDelegate(base::WeakPtr<PolicyWatcherLinux> policy_watcher)
: policy_watcher_(policy_watcher) {
}
@@ -123,11 +123,11 @@
virtual ~FilePathWatcherDelegate() {}
private:
- base::WeakPtr<NatPolicyLinux> policy_watcher_;
+ base::WeakPtr<PolicyWatcherLinux> policy_watcher_;
};
base::Time GetLastModification() {
- DCHECK(OnPolicyThread());
+ DCHECK(OnPolicyWatcherThread());
base::Time last_modification = base::Time();
base::PlatformFileInfo file_info;
@@ -156,7 +156,7 @@
// Caller owns the value.
DictionaryValue* Load() {
- DCHECK(OnPolicyThread());
+ DCHECK(OnPolicyWatcherThread());
// Enumerate the files and sort them lexicographically.
std::set<FilePath> files;
file_util::FileEnumerator file_enumerator(config_dir_, false,
@@ -192,7 +192,7 @@
}
void Reload() {
- DCHECK(OnPolicyThread());
+ DCHECK(OnPolicyWatcherThread());
// Check the directory time in order to see whether a reload is required.
base::TimeDelta delay;
base::Time now = base::Time::Now();
@@ -209,13 +209,13 @@
// Load the policy definitions.
scoped_ptr<DictionaryValue> new_policy(Load());
- UpdateNatPolicy(new_policy.get());
+ UpdatePolicies(new_policy.get());
ScheduleFallbackReloadTask();
}
bool IsSafeToReloadPolicy(const base::Time& now, base::TimeDelta* delay) {
- DCHECK(OnPolicyThread());
+ DCHECK(OnPolicyWatcherThread());
DCHECK(delay);
const base::TimeDelta kSettleInterval =
base::TimeDelta::FromSeconds(kSettleIntervalSeconds);
@@ -247,10 +247,10 @@
}
// Managed with a scoped_ptr rather than being declared as an inline member to
- // decouple the watcher's life cycle from the NatPolicyLinux. This decoupling
- // makes it possible to destroy the watcher before the loader's destructor is
- // called (e.g. during Stop), since |watcher_| internally holds a reference to
- // the loader and keeps it alive.
+ // decouple the watcher's life cycle from the PolicyWatcherLinux. This
+ // decoupling makes it possible to destroy the watcher before the loader's
+ // destructor is called (e.g. during Stop), since |watcher_| internally holds
+ // a reference to the loader and keeps it alive.
scoped_ptr<base::files::FilePathWatcher> watcher_;
// Records last known modification timestamp of |config_dir_|.
@@ -265,13 +265,13 @@
const FilePath config_dir_;
// Allows us to cancel any inflight FileWatcher events or scheduled reloads.
- base::WeakPtrFactory<NatPolicyLinux> weak_factory_;
+ base::WeakPtrFactory<PolicyWatcherLinux> weak_factory_;
};
-NatPolicy* NatPolicy::Create(
+PolicyWatcher* PolicyWatcher::Create(
scoped_refptr<base::SingleThreadTaskRunner> task_runner) {
FilePath policy_dir(kPolicyDir);
- return new NatPolicyLinux(task_runner, policy_dir);
+ return new PolicyWatcherLinux(task_runner, policy_dir);
}
} // namespace policy_hack
diff --git a/remoting/host/policy_hack/nat_policy_mac.mm b/remoting/host/policy_hack/policy_watcher_mac.mm
similarity index 60%
rename from remoting/host/policy_hack/nat_policy_mac.mm
rename to remoting/host/policy_hack/policy_watcher_mac.mm
index d3d2621..eee0412b 100644
--- a/remoting/host/policy_hack/nat_policy_mac.mm
+++ b/remoting/host/policy_hack/policy_watcher_mac.mm
@@ -2,7 +2,7 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-#include "remoting/host/policy_hack/nat_policy.h"
+#include "remoting/host/policy_hack/policy_watcher.h"
#include <CoreFoundation/CoreFoundation.h>
@@ -20,13 +20,14 @@
// practice on the Mac that the user must logout/login for policies to be
// applied. This will actually pick up policies every
// |kFallbackReloadDelayMinutes| which is sufficient for right now.
-class NatPolicyMac : public NatPolicy {
+class PolicyWatcherMac : public PolicyWatcher {
public:
- explicit NatPolicyMac(scoped_refptr<base::SingleThreadTaskRunner> task_runner)
- : NatPolicy(task_runner) {
+ explicit PolicyWatcherMac(
+ scoped_refptr<base::SingleThreadTaskRunner> task_runner)
+ : PolicyWatcher(task_runner) {
}
- virtual ~NatPolicyMac() {
+ virtual ~PolicyWatcherMac() {
}
protected:
@@ -38,34 +39,37 @@
}
virtual void Reload() OVERRIDE {
- DCHECK(OnPolicyThread());
+ DCHECK(OnPolicyWatcherThread());
base::DictionaryValue policy;
CFStringRef policy_bundle_id = CFSTR("com.google.Chrome");
if (CFPreferencesAppSynchronize(policy_bundle_id)) {
- base::mac::ScopedCFTypeRef<CFStringRef> policy_key(
- base::SysUTF8ToCFStringRef(kNatPolicyName));
- Boolean valid = false;
- bool allowed = CFPreferencesGetAppBooleanValue(policy_key,
- policy_bundle_id,
- &valid);
- if (valid) {
- policy.SetBoolean(kNatPolicyName, allowed);
+ for (int i = 0; i < kBooleanPolicyNamesNum; ++i) {
+ const char* policy_name = kBooleanPolicyNames[i];
+ base::mac::ScopedCFTypeRef<CFStringRef> policy_key(
+ base::SysUTF8ToCFStringRef(policy_name));
+ Boolean valid = false;
+ bool allowed = CFPreferencesGetAppBooleanValue(policy_key,
+ policy_bundle_id,
+ &valid);
+ if (valid) {
+ policy.SetBoolean(policy_name, allowed);
+ }
}
}
// Set policy. Policy must be set (even if it is empty) so that the
// default policy is picked up the first time reload is called.
- UpdateNatPolicy(&policy);
+ UpdatePolicies(&policy);
// Reschedule task.
ScheduleFallbackReloadTask();
}
};
-NatPolicy* NatPolicy::Create(
+PolicyWatcher* PolicyWatcher::Create(
scoped_refptr<base::SingleThreadTaskRunner> task_runner) {
- return new NatPolicyMac(task_runner);
+ return new PolicyWatcherMac(task_runner);
}
} // namespace policy_hack
diff --git a/remoting/host/policy_hack/policy_watcher_unittest.cc b/remoting/host/policy_hack/policy_watcher_unittest.cc
new file mode 100644
index 0000000..38293537
--- /dev/null
+++ b/remoting/host/policy_hack/policy_watcher_unittest.cc
@@ -0,0 +1,150 @@
+// Copyright (c) 2012 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "base/basictypes.h"
+#include "base/bind.h"
+#include "base/message_loop.h"
+#include "base/synchronization/waitable_event.h"
+#include "remoting/host/policy_hack/fake_policy_watcher.h"
+#include "remoting/host/policy_hack/mock_policy_callback.h"
+#include "remoting/host/policy_hack/policy_watcher.h"
+#include "testing/gmock/include/gmock/gmock.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+namespace remoting {
+namespace policy_hack {
+
+class PolicyWatcherTest : public testing::Test {
+ public:
+ PolicyWatcherTest() {
+ }
+
+ virtual void SetUp() OVERRIDE {
+ message_loop_proxy_ = base::MessageLoopProxy::current();
+ policy_callback_ = base::Bind(&MockPolicyCallback::OnPolicyUpdate,
+ base::Unretained(&mock_policy_callback_));
+ policy_watcher_.reset(new FakePolicyWatcher(message_loop_proxy_));
+ nat_true.SetBoolean(PolicyWatcher::kNatPolicyName, true);
+ nat_false.SetBoolean(PolicyWatcher::kNatPolicyName, false);
+ nat_one.SetInteger(PolicyWatcher::kNatPolicyName, 1);
+ }
+
+ protected:
+ void StartWatching() {
+ policy_watcher_->StartWatching(policy_callback_);
+ message_loop_.RunUntilIdle();
+ }
+
+ void StopWatching() {
+ base::WaitableEvent stop_event(false, false);
+ policy_watcher_->StopWatching(&stop_event);
+ message_loop_.RunUntilIdle();
+ EXPECT_EQ(true, stop_event.IsSignaled());
+ }
+
+ MessageLoop message_loop_;
+ scoped_refptr<base::MessageLoopProxy> message_loop_proxy_;
+ MockPolicyCallback mock_policy_callback_;
+ PolicyWatcher::PolicyCallback policy_callback_;
+ scoped_ptr<FakePolicyWatcher> policy_watcher_;
+ base::DictionaryValue empty;
+ base::DictionaryValue nat_true;
+ base::DictionaryValue nat_false;
+ base::DictionaryValue nat_one;
+};
+
+MATCHER_P(IsPolicies, dict, "") {
+ return arg->Equals(dict);
+}
+
+TEST_F(PolicyWatcherTest, None) {
+ EXPECT_CALL(mock_policy_callback_, OnPolicyUpdatePtr(IsPolicies(&nat_true)));
+
+ StartWatching();
+ policy_watcher_->SetPolicies(&empty);
+ StopWatching();
+}
+
+TEST_F(PolicyWatcherTest, NatTrue) {
+ EXPECT_CALL(mock_policy_callback_, OnPolicyUpdatePtr(IsPolicies(&nat_true)));
+
+ StartWatching();
+ policy_watcher_->SetPolicies(&nat_true);
+ StopWatching();
+}
+
+TEST_F(PolicyWatcherTest, NatFalse) {
+ EXPECT_CALL(mock_policy_callback_, OnPolicyUpdatePtr(IsPolicies(&nat_false)));
+
+ StartWatching();
+ policy_watcher_->SetPolicies(&nat_false);
+ StopWatching();
+}
+
+TEST_F(PolicyWatcherTest, NatOne) {
+ EXPECT_CALL(mock_policy_callback_, OnPolicyUpdatePtr(IsPolicies(&nat_false)));
+
+ StartWatching();
+ policy_watcher_->SetPolicies(&nat_one);
+ StopWatching();
+}
+
+TEST_F(PolicyWatcherTest, NatNoneThenTrue) {
+ EXPECT_CALL(mock_policy_callback_, OnPolicyUpdatePtr(IsPolicies(&nat_true)));
+
+ StartWatching();
+ policy_watcher_->SetPolicies(&empty);
+ policy_watcher_->SetPolicies(&nat_true);
+ StopWatching();
+}
+
+TEST_F(PolicyWatcherTest, NatNoneThenTrueThenTrue) {
+ EXPECT_CALL(mock_policy_callback_, OnPolicyUpdatePtr(IsPolicies(&nat_true)));
+
+ StartWatching();
+ policy_watcher_->SetPolicies(&empty);
+ policy_watcher_->SetPolicies(&nat_true);
+ policy_watcher_->SetPolicies(&nat_true);
+ StopWatching();
+}
+
+TEST_F(PolicyWatcherTest, NatNoneThenTrueThenTrueThenFalse) {
+ testing::InSequence sequence;
+ EXPECT_CALL(mock_policy_callback_, OnPolicyUpdatePtr(IsPolicies(&nat_true)));
+ EXPECT_CALL(mock_policy_callback_, OnPolicyUpdatePtr(IsPolicies(&nat_false)));
+
+ StartWatching();
+ policy_watcher_->SetPolicies(&empty);
+ policy_watcher_->SetPolicies(&nat_true);
+ policy_watcher_->SetPolicies(&nat_true);
+ policy_watcher_->SetPolicies(&nat_false);
+ StopWatching();
+}
+
+TEST_F(PolicyWatcherTest, NatNoneThenFalse) {
+ testing::InSequence sequence;
+ EXPECT_CALL(mock_policy_callback_, OnPolicyUpdatePtr(IsPolicies(&nat_true)));
+ EXPECT_CALL(mock_policy_callback_, OnPolicyUpdatePtr(IsPolicies(&nat_false)));
+
+ StartWatching();
+ policy_watcher_->SetPolicies(&empty);
+ policy_watcher_->SetPolicies(&nat_false);
+ StopWatching();
+}
+
+TEST_F(PolicyWatcherTest, NatNoneThenFalseThenTrue) {
+ testing::InSequence sequence;
+ EXPECT_CALL(mock_policy_callback_, OnPolicyUpdatePtr(IsPolicies(&nat_true)));
+ EXPECT_CALL(mock_policy_callback_, OnPolicyUpdatePtr(IsPolicies(&nat_false)));
+ EXPECT_CALL(mock_policy_callback_, OnPolicyUpdatePtr(IsPolicies(&nat_true)));
+
+ StartWatching();
+ policy_watcher_->SetPolicies(&empty);
+ policy_watcher_->SetPolicies(&nat_false);
+ policy_watcher_->SetPolicies(&nat_true);
+ StopWatching();
+}
+
+} // namespace policy_hack
+} // namespace remoting
diff --git a/remoting/host/policy_hack/nat_policy_win.cc b/remoting/host/policy_hack/policy_watcher_win.cc
similarity index 85%
rename from remoting/host/policy_hack/nat_policy_win.cc
rename to remoting/host/policy_hack/policy_watcher_win.cc
index d09d39d..5c247d6 100644
--- a/remoting/host/policy_hack/nat_policy_win.cc
+++ b/remoting/host/policy_hack/policy_watcher_win.cc
@@ -10,7 +10,7 @@
//
// This is a reduction of the functionality in those classes.
-#include "remoting/host/policy_hack/nat_policy.h"
+#include "remoting/host/policy_hack/policy_watcher.h"
#include <userenv.h>
@@ -38,23 +38,24 @@
} // namespace
-class NatPolicyWin :
- public NatPolicy,
+class PolicyWatcherWin :
+ public PolicyWatcher,
public base::win::ObjectWatcher::Delegate {
public:
- explicit NatPolicyWin(scoped_refptr<base::SingleThreadTaskRunner> task_runner)
- : NatPolicy(task_runner),
+ explicit PolicyWatcherWin(
+ scoped_refptr<base::SingleThreadTaskRunner> task_runner)
+ : PolicyWatcher(task_runner),
user_policy_changed_event_(false, false),
machine_policy_changed_event_(false, false),
user_policy_watcher_failed_(false),
machine_policy_watcher_failed_(false) {
}
- virtual ~NatPolicyWin() {
+ virtual ~PolicyWatcherWin() {
}
virtual void StartWatchingInternal() OVERRIDE {
- DCHECK(OnPolicyThread());
+ DCHECK(OnPolicyWatcherThread());
if (!RegisterGPNotification(user_policy_changed_event_.handle(), false)) {
PLOG(WARNING) << "Failed to register user group policy notification";
@@ -70,7 +71,7 @@
}
virtual void StopWatchingInternal() OVERRIDE {
- DCHECK(OnPolicyThread());
+ DCHECK(OnPolicyWatcherThread());
if (!UnregisterGPNotification(user_policy_changed_event_.handle())) {
PLOG(WARNING) << "Failed to unregister user group policy notification";
@@ -88,7 +89,7 @@
private:
// Updates the watchers and schedules the reload task if appropriate.
void SetupWatches() {
- DCHECK(OnPolicyThread());
+ DCHECK(OnPolicyWatcherThread());
if (!user_policy_watcher_failed_ &&
!user_policy_watcher_.GetWatchedObject() &&
@@ -142,10 +143,13 @@
base::DictionaryValue* Load() {
base::DictionaryValue* policy = new base::DictionaryValue();
- bool bool_value;
- const string16 name(ASCIIToUTF16(kNatPolicyName));
- if (GetRegistryPolicyBoolean(name, &bool_value)) {
- policy->SetBoolean(kNatPolicyName, bool_value);
+ for (int i = 0; i < kBooleanPolicyNamesNum; ++i) {
+ const char* policy_name = kBooleanPolicyNames[i];
+ bool bool_value;
+ const string16 name(ASCIIToUTF16(policy_name));
+ if (GetRegistryPolicyBoolean(name, &bool_value)) {
+ policy->SetBoolean(policy_name, bool_value);
+ }
}
return policy;
@@ -153,15 +157,15 @@
// Post a reload notification and update the watch machinery.
void Reload() {
- DCHECK(OnPolicyThread());
+ DCHECK(OnPolicyWatcherThread());
SetupWatches();
scoped_ptr<DictionaryValue> new_policy(Load());
- UpdateNatPolicy(new_policy.get());
+ UpdatePolicies(new_policy.get());
}
// ObjectWatcher::Delegate overrides:
virtual void OnObjectSignaled(HANDLE object) {
- DCHECK(OnPolicyThread());
+ DCHECK(OnPolicyWatcherThread());
DCHECK(object == user_policy_changed_event_.handle() ||
object == machine_policy_changed_event_.handle())
<< "unexpected object signaled policy reload, obj = "
@@ -177,9 +181,9 @@
bool machine_policy_watcher_failed_;
};
-NatPolicy* NatPolicy::Create(
+PolicyWatcher* PolicyWatcher::Create(
scoped_refptr<base::SingleThreadTaskRunner> task_runner) {
- return new NatPolicyWin(task_runner);
+ return new PolicyWatcherWin(task_runner);
}
} // namespace policy_hack
diff --git a/remoting/host/remoting_me2me_host.cc b/remoting/host/remoting_me2me_host.cc
index 848d5bb..18822ea 100644
--- a/remoting/host/remoting_me2me_host.cc
+++ b/remoting/host/remoting_me2me_host.cc
@@ -41,7 +41,7 @@
#include "remoting/host/json_host_config.h"
#include "remoting/host/log_to_server.h"
#include "remoting/host/network_settings.h"
-#include "remoting/host/policy_hack/nat_policy.h"
+#include "remoting/host/policy_hack/policy_watcher.h"
#include "remoting/host/session_manager_factory.h"
#include "remoting/host/signaling_connector.h"
#include "remoting/host/usage_stats_consent.h"
@@ -213,7 +213,7 @@
host_user_interface_.reset(new HostUserInterface(context_.get()));
#endif
- StartWatchingNatPolicy();
+ StartWatchingPolicy();
#if defined(OS_MACOSX) || defined(OS_WIN)
context_->file_task_runner()->PostTask(
@@ -228,9 +228,9 @@
#endif
base::WaitableEvent done_event(true, false);
- nat_policy_->StopWatching(&done_event);
+ policy_watcher_->StopWatching(&done_event);
done_event.Wait();
- nat_policy_.reset();
+ policy_watcher_.reset();
return exit_code_;
}
@@ -242,11 +242,11 @@
}
private:
- void StartWatchingNatPolicy() {
- nat_policy_.reset(
- policy_hack::NatPolicy::Create(context_->file_task_runner()));
- nat_policy_->StartWatching(
- base::Bind(&HostProcess::OnNatPolicyUpdate, base::Unretained(this)));
+ void StartWatchingPolicy() {
+ policy_watcher_.reset(
+ policy_hack::PolicyWatcher::Create(context_->file_task_runner()));
+ policy_watcher_->StartWatching(
+ base::Bind(&HostProcess::OnPolicyUpdate, base::Unretained(this)));
}
// Read Host config from disk, returning true if successful.
@@ -314,6 +314,21 @@
return true;
}
+ void OnPolicyUpdate(scoped_ptr<base::DictionaryValue> policies) {
+ if (!context_->network_task_runner()->BelongsToCurrentThread()) {
+ context_->network_task_runner()->PostTask(FROM_HERE, base::Bind(
+ &HostProcess::OnPolicyUpdate, base::Unretained(this),
+ base::Passed(&policies)));
+ return;
+ }
+
+ bool bool_value;
+ if (policies->GetBoolean(policy_hack::PolicyWatcher::kNatPolicyName,
+ &bool_value)) {
+ OnNatPolicyUpdate(bool_value);
+ }
+ }
+
void OnNatPolicyUpdate(bool nat_traversal_enabled) {
if (!context_->network_task_runner()->BelongsToCurrentThread()) {
context_->network_task_runner()->PostTask(FROM_HERE, base::Bind(
@@ -498,7 +513,7 @@
std::string oauth_refresh_token_;
bool oauth_use_official_client_id_;
- scoped_ptr<policy_hack::NatPolicy> nat_policy_;
+ scoped_ptr<policy_hack::PolicyWatcher> policy_watcher_;
bool allow_nat_traversal_;
scoped_ptr<base::files::FilePathWatcher> config_watcher_;
scoped_ptr<base::DelayTimer<HostProcess> > config_updated_timer_;
diff --git a/remoting/remoting.gyp b/remoting/remoting.gyp
index feaebad6..a2a39a8 100644
--- a/remoting/remoting.gyp
+++ b/remoting/remoting.gyp
@@ -1182,11 +1182,11 @@
'host/network_settings.h',
'host/pin_hash.cc',
'host/pin_hash.h',
- 'host/policy_hack/nat_policy.h',
- 'host/policy_hack/nat_policy.cc',
- 'host/policy_hack/nat_policy_linux.cc',
- 'host/policy_hack/nat_policy_mac.mm',
- 'host/policy_hack/nat_policy_win.cc',
+ 'host/policy_hack/policy_watcher.h',
+ 'host/policy_hack/policy_watcher.cc',
+ 'host/policy_hack/policy_watcher_linux.cc',
+ 'host/policy_hack/policy_watcher_mac.mm',
+ 'host/policy_hack/policy_watcher_win.cc',
'host/register_support_host_request.cc',
'host/register_support_host_request.h',
'host/remote_input_filter.cc',
@@ -1700,6 +1700,11 @@
'host/json_host_config_unittest.cc',
'host/log_to_server_unittest.cc',
'host/pin_hash_unittest.cc',
+ 'host/policy_hack/fake_policy_watcher.cc',
+ 'host/policy_hack/fake_policy_watcher.h',
+ 'host/policy_hack/mock_policy_callback.cc',
+ 'host/policy_hack/mock_policy_callback.h',
+ 'host/policy_hack/policy_watcher_unittest.cc',
'host/register_support_host_request_unittest.cc',
'host/remote_input_filter_unittest.cc',
'host/screen_recorder_unittest.cc',