blob: f0d4937d94248826042e693186bee5fa882beb0b [file] [log] [blame]
Alex Deymoc705cc82014-02-19 11:15:00 -08001// Copyright (c) 2014 The Chromium OS 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
Gilad Arnold2cbb3852014-03-07 12:40:50 -08005#ifndef CHROMEOS_PLATFORM_UPDATE_ENGINE_POLICY_MANAGER_POLICY_MANAGER_INL_H_
6#define CHROMEOS_PLATFORM_UPDATE_ENGINE_POLICY_MANAGER_POLICY_MANAGER_INL_H_
Alex Deymoc705cc82014-02-19 11:15:00 -08007
Alex Deymo53556ec2014-03-17 10:05:57 -07008#include <string>
9
Alex Deymo7b948f02014-03-10 17:01:10 -070010#include <base/bind.h>
11
Alex Deymoc705cc82014-02-19 11:15:00 -080012#include "update_engine/policy_manager/evaluation_context.h"
Alex Deymo53556ec2014-03-17 10:05:57 -070013#include "update_engine/policy_manager/event_loop.h"
Alex Deymoc705cc82014-02-19 11:15:00 -080014
15namespace chromeos_policy_manager {
16
Alex Deymoc705cc82014-02-19 11:15:00 -080017template<typename T, typename R, typename... Args>
Alex Deymo7b948f02014-03-10 17:01:10 -070018EvalStatus PolicyManager::EvaluatePolicy(EvaluationContext* ec,
19 T policy_method, R* result,
20 Args... args) {
Alex Deymoc705cc82014-02-19 11:15:00 -080021 std::string error;
22
23 // First try calling the actual policy.
Alex Deymo7b948f02014-03-10 17:01:10 -070024 EvalStatus status = (policy_.get()->*policy_method)(ec, state_.get(), &error,
Alex Deymo2de23f52014-02-26 14:30:13 -080025 result, args...);
Alex Deymoc705cc82014-02-19 11:15:00 -080026
Alex Deymoe636c3c2014-03-11 19:02:08 -070027 if (status == EvalStatus::kFailed) {
Alex Deymoc705cc82014-02-19 11:15:00 -080028 LOG(WARNING) << "PolicyRequest() failed with error: " << error;
29 error.clear();
Alex Deymo7b948f02014-03-10 17:01:10 -070030 status = (default_policy_.*policy_method)(ec, state_.get(), &error,
Alex Deymo2de23f52014-02-26 14:30:13 -080031 result, args...);
Alex Deymoc705cc82014-02-19 11:15:00 -080032
Alex Deymoe636c3c2014-03-11 19:02:08 -070033 if (status == EvalStatus::kFailed) {
Alex Deymoc705cc82014-02-19 11:15:00 -080034 LOG(WARNING) << "Request to DefaultPolicy also failed, passing error.";
35 }
36 }
37 // TODO(deymo): Log the actual state used from the EvaluationContext.
38 return status;
39}
40
Alex Deymo7b948f02014-03-10 17:01:10 -070041template<typename T, typename R, typename... Args>
42void PolicyManager::OnPolicyReadyToEvaluate(
43 scoped_refptr<EvaluationContext> ec,
44 base::Callback<void(EvalStatus status, const R& result)> callback,
45 T policy_method, Args... args) {
46 R result;
47 EvalStatus status = EvaluatePolicy(ec, policy_method, &result, args...);
48
49 if (status != EvalStatus::kAskMeAgainLater) {
50 // AsyncPolicyRequest finished.
51 callback.Run(status, result);
52 return;
53 }
Alex Deymo53556ec2014-03-17 10:05:57 -070054 // Re-schedule the policy request based on used variables.
Alex Deymo7b948f02014-03-10 17:01:10 -070055 base::Closure closure = base::Bind(
56 &PolicyManager::OnPolicyReadyToEvaluate<T, R, Args...>,
57 base::Unretained(this), ec, callback, policy_method, args...);
Alex Deymo53556ec2014-03-17 10:05:57 -070058
59 if (!ec->RunOnValueChangeOrTimeout(closure)) {
60 // The policy method didn't use any non-const variable nor there's any
61 // time-based event that will change the status of evaluation. We call the
62 // callback with EvalStatus::kAskMeAgainLater.
63 LOG(ERROR) << "Policy implementation didn't use any non-const variable "
64 "but returned kAskMeAgainLater.";
65 callback.Run(EvalStatus::kAskMeAgainLater, result);
66 return;
67 }
Alex Deymo7b948f02014-03-10 17:01:10 -070068}
69
70template<typename T, typename R, typename... Args>
71EvalStatus PolicyManager::PolicyRequest(T policy_method, R* result,
72 Args... args) {
73 scoped_refptr<EvaluationContext> ec(new EvaluationContext);
74 // A PolicyRequest allways consists on a single evaluation on a new
75 // EvaluationContext.
76 return EvaluatePolicy(ec, policy_method, result, args...);
77}
78
79template<typename T, typename R, typename... Args>
80void PolicyManager::AsyncPolicyRequest(
81 base::Callback<void(EvalStatus, const R& result)> callback,
82 T policy_method, Args... args) {
83
84 scoped_refptr<EvaluationContext> ec = new EvaluationContext;
85 base::Closure closure = base::Bind(
86 &PolicyManager::OnPolicyReadyToEvaluate<T, R, Args...>,
87 base::Unretained(this), ec, callback, policy_method, args...);
88 RunFromMainLoop(closure);
89}
90
Alex Deymoc705cc82014-02-19 11:15:00 -080091} // namespace chromeos_policy_manager
92
Gilad Arnold2cbb3852014-03-07 12:40:50 -080093#endif // CHROMEOS_PLATFORM_UPDATE_ENGINE_POLICY_MANAGER_POLICY_MANAGER_INL_H_