blob: 7ff6fa6c86134d26a0b28cfe4232a6316a1aab48 [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 Deymoe75e0252014-04-08 14:00:11 -070017template<typename R, typename... Args>
18EvalStatus PolicyManager::EvaluatePolicy(
19 EvaluationContext* ec,
20 EvalStatus (Policy::*policy_method)(EvaluationContext* ec,
21 State* state,
22 std::string* error,
23 R* result,
24 Args... args) const,
25 R* result, Args... args) {
Alex Deymoc705cc82014-02-19 11:15:00 -080026 std::string error;
27
28 // First try calling the actual policy.
Alex Deymo7b948f02014-03-10 17:01:10 -070029 EvalStatus status = (policy_.get()->*policy_method)(ec, state_.get(), &error,
Alex Deymo2de23f52014-02-26 14:30:13 -080030 result, args...);
Alex Deymoc705cc82014-02-19 11:15:00 -080031
Alex Deymoe636c3c2014-03-11 19:02:08 -070032 if (status == EvalStatus::kFailed) {
Alex Deymoc705cc82014-02-19 11:15:00 -080033 LOG(WARNING) << "PolicyRequest() failed with error: " << error;
34 error.clear();
Alex Deymo7b948f02014-03-10 17:01:10 -070035 status = (default_policy_.*policy_method)(ec, state_.get(), &error,
Alex Deymo2de23f52014-02-26 14:30:13 -080036 result, args...);
Alex Deymoc705cc82014-02-19 11:15:00 -080037
Alex Deymoe636c3c2014-03-11 19:02:08 -070038 if (status == EvalStatus::kFailed) {
Alex Deymoc705cc82014-02-19 11:15:00 -080039 LOG(WARNING) << "Request to DefaultPolicy also failed, passing error.";
40 }
41 }
42 // TODO(deymo): Log the actual state used from the EvaluationContext.
43 return status;
44}
45
Alex Deymoe75e0252014-04-08 14:00:11 -070046template<typename R, typename... Args>
Alex Deymo7b948f02014-03-10 17:01:10 -070047void PolicyManager::OnPolicyReadyToEvaluate(
48 scoped_refptr<EvaluationContext> ec,
49 base::Callback<void(EvalStatus status, const R& result)> callback,
Alex Deymoe75e0252014-04-08 14:00:11 -070050 EvalStatus (Policy::*policy_method)(EvaluationContext* ec,
51 State* state,
52 std::string* error,
53 R* result,
54 Args... args) const,
55 Args... args) {
Alex Deymo41a75a72014-04-15 15:36:22 -070056 ec->ResetEvaluation();
Alex Deymo7b948f02014-03-10 17:01:10 -070057 R result;
58 EvalStatus status = EvaluatePolicy(ec, policy_method, &result, args...);
59
60 if (status != EvalStatus::kAskMeAgainLater) {
61 // AsyncPolicyRequest finished.
62 callback.Run(status, result);
63 return;
64 }
Alex Deymo53556ec2014-03-17 10:05:57 -070065 // Re-schedule the policy request based on used variables.
Alex Deymo7b948f02014-03-10 17:01:10 -070066 base::Closure closure = base::Bind(
Alex Deymoe75e0252014-04-08 14:00:11 -070067 &PolicyManager::OnPolicyReadyToEvaluate<R, Args...>,
Alex Deymo7b948f02014-03-10 17:01:10 -070068 base::Unretained(this), ec, callback, policy_method, args...);
Alex Deymo53556ec2014-03-17 10:05:57 -070069
70 if (!ec->RunOnValueChangeOrTimeout(closure)) {
71 // The policy method didn't use any non-const variable nor there's any
72 // time-based event that will change the status of evaluation. We call the
73 // callback with EvalStatus::kAskMeAgainLater.
74 LOG(ERROR) << "Policy implementation didn't use any non-const variable "
75 "but returned kAskMeAgainLater.";
76 callback.Run(EvalStatus::kAskMeAgainLater, result);
77 return;
78 }
Alex Deymo7b948f02014-03-10 17:01:10 -070079}
80
Alex Deymoe75e0252014-04-08 14:00:11 -070081template<typename R, typename... Args>
82EvalStatus PolicyManager::PolicyRequest(
83 EvalStatus (Policy::*policy_method)(EvaluationContext* ec,
84 State* state,
85 std::string* error,
86 R* result,
87 Args... args) const,
88 R* result, Args... args) {
Alex Deymo41a75a72014-04-15 15:36:22 -070089 scoped_refptr<EvaluationContext> ec(new EvaluationContext(clock_));
Alex Deymo7b948f02014-03-10 17:01:10 -070090 // A PolicyRequest allways consists on a single evaluation on a new
91 // EvaluationContext.
92 return EvaluatePolicy(ec, policy_method, result, args...);
93}
94
Alex Deymoe75e0252014-04-08 14:00:11 -070095template<typename R, typename... Args>
Alex Deymo7b948f02014-03-10 17:01:10 -070096void PolicyManager::AsyncPolicyRequest(
97 base::Callback<void(EvalStatus, const R& result)> callback,
Alex Deymoe75e0252014-04-08 14:00:11 -070098 EvalStatus (Policy::*policy_method)(EvaluationContext* ec,
99 State* state,
100 std::string* error,
101 R* result,
102 Args... args) const,
103 Args... args) {
Alex Deymo41a75a72014-04-15 15:36:22 -0700104 scoped_refptr<EvaluationContext> ec = new EvaluationContext(clock_);
Alex Deymo7b948f02014-03-10 17:01:10 -0700105 base::Closure closure = base::Bind(
Alex Deymoe75e0252014-04-08 14:00:11 -0700106 &PolicyManager::OnPolicyReadyToEvaluate<R, Args...>,
Alex Deymo7b948f02014-03-10 17:01:10 -0700107 base::Unretained(this), ec, callback, policy_method, args...);
108 RunFromMainLoop(closure);
109}
110
Alex Deymoc705cc82014-02-19 11:15:00 -0800111} // namespace chromeos_policy_manager
112
Gilad Arnold2cbb3852014-03-07 12:40:50 -0800113#endif // CHROMEOS_PLATFORM_UPDATE_ENGINE_POLICY_MANAGER_POLICY_MANAGER_INL_H_