blob: 81cc808ecd2f7767cefa04d84b17a3f8c5c55cf6 [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,
Gilad Arnold13a82432014-05-19 12:52:44 -070020 EvalStatus (Policy::*policy_method)(EvaluationContext*, State*,
21 std::string*, R*,
22 Args...) const,
Alex Deymoe75e0252014-04-08 14:00:11 -070023 R* result, Args... args) {
Alex Deymoc705cc82014-02-19 11:15:00 -080024 std::string error;
25
26 // First try calling the actual policy.
Alex Deymo7b948f02014-03-10 17:01:10 -070027 EvalStatus status = (policy_.get()->*policy_method)(ec, state_.get(), &error,
Alex Deymo2de23f52014-02-26 14:30:13 -080028 result, args...);
Alex Deymoc705cc82014-02-19 11:15:00 -080029
Alex Deymoe636c3c2014-03-11 19:02:08 -070030 if (status == EvalStatus::kFailed) {
Alex Deymoc705cc82014-02-19 11:15:00 -080031 LOG(WARNING) << "PolicyRequest() failed with error: " << error;
32 error.clear();
Alex Deymo7b948f02014-03-10 17:01:10 -070033 status = (default_policy_.*policy_method)(ec, state_.get(), &error,
Alex Deymo2de23f52014-02-26 14:30:13 -080034 result, args...);
Alex Deymoc705cc82014-02-19 11:15:00 -080035
Alex Deymoe636c3c2014-03-11 19:02:08 -070036 if (status == EvalStatus::kFailed) {
Alex Deymoc705cc82014-02-19 11:15:00 -080037 LOG(WARNING) << "Request to DefaultPolicy also failed, passing error.";
38 }
39 }
40 // TODO(deymo): Log the actual state used from the EvaluationContext.
41 return status;
42}
43
Alex Deymoe75e0252014-04-08 14:00:11 -070044template<typename R, typename... Args>
Alex Deymo7b948f02014-03-10 17:01:10 -070045void PolicyManager::OnPolicyReadyToEvaluate(
46 scoped_refptr<EvaluationContext> ec,
47 base::Callback<void(EvalStatus status, const R& result)> callback,
Gilad Arnold13a82432014-05-19 12:52:44 -070048 EvalStatus (Policy::*policy_method)(EvaluationContext*, State*,
49 std::string*, R*,
50 Args...) const,
Alex Deymoe75e0252014-04-08 14:00:11 -070051 Args... args) {
Alex Deymo41a75a72014-04-15 15:36:22 -070052 ec->ResetEvaluation();
Alex Deymo7b948f02014-03-10 17:01:10 -070053 R result;
54 EvalStatus status = EvaluatePolicy(ec, policy_method, &result, args...);
55
56 if (status != EvalStatus::kAskMeAgainLater) {
57 // AsyncPolicyRequest finished.
58 callback.Run(status, result);
59 return;
60 }
Alex Deymo53556ec2014-03-17 10:05:57 -070061 // Re-schedule the policy request based on used variables.
Alex Deymo7b948f02014-03-10 17:01:10 -070062 base::Closure closure = base::Bind(
Alex Deymoe75e0252014-04-08 14:00:11 -070063 &PolicyManager::OnPolicyReadyToEvaluate<R, Args...>,
Alex Deymo7b948f02014-03-10 17:01:10 -070064 base::Unretained(this), ec, callback, policy_method, args...);
Alex Deymo53556ec2014-03-17 10:05:57 -070065
66 if (!ec->RunOnValueChangeOrTimeout(closure)) {
67 // The policy method didn't use any non-const variable nor there's any
68 // time-based event that will change the status of evaluation. We call the
69 // callback with EvalStatus::kAskMeAgainLater.
70 LOG(ERROR) << "Policy implementation didn't use any non-const variable "
71 "but returned kAskMeAgainLater.";
72 callback.Run(EvalStatus::kAskMeAgainLater, result);
73 return;
74 }
Alex Deymo7b948f02014-03-10 17:01:10 -070075}
76
Gilad Arnold13a82432014-05-19 12:52:44 -070077template<typename R, typename... ActualArgs, typename... ExpectedArgs>
Alex Deymoe75e0252014-04-08 14:00:11 -070078EvalStatus PolicyManager::PolicyRequest(
Gilad Arnold13a82432014-05-19 12:52:44 -070079 EvalStatus (Policy::*policy_method)(EvaluationContext*, State*,
80 std::string*, R*,
81 ExpectedArgs...) const,
82 R* result, ActualArgs... args) {
Alex Deymo41a75a72014-04-15 15:36:22 -070083 scoped_refptr<EvaluationContext> ec(new EvaluationContext(clock_));
Alex Deymo7b948f02014-03-10 17:01:10 -070084 // A PolicyRequest allways consists on a single evaluation on a new
85 // EvaluationContext.
Gilad Arnold13a82432014-05-19 12:52:44 -070086 // IMPORTANT: To ensure that ActualArgs can be converted to ExpectedArgs, we
87 // explicitly instantiate EvaluatePolicy with the latter in lieu of the
88 // former.
89 return EvaluatePolicy<R, ExpectedArgs...>(ec, policy_method, result, args...);
Alex Deymo7b948f02014-03-10 17:01:10 -070090}
91
Gilad Arnold13a82432014-05-19 12:52:44 -070092template<typename R, typename... ActualArgs, typename... ExpectedArgs>
Alex Deymo7b948f02014-03-10 17:01:10 -070093void PolicyManager::AsyncPolicyRequest(
94 base::Callback<void(EvalStatus, const R& result)> callback,
Gilad Arnold13a82432014-05-19 12:52:44 -070095 EvalStatus (Policy::*policy_method)(EvaluationContext*, State*,
96 std::string*, R*,
97 ExpectedArgs...) const,
98 ActualArgs... args) {
Alex Deymo41a75a72014-04-15 15:36:22 -070099 scoped_refptr<EvaluationContext> ec = new EvaluationContext(clock_);
Gilad Arnold13a82432014-05-19 12:52:44 -0700100 // IMPORTANT: To ensure that ActualArgs can be converted to ExpectedArgs, we
101 // explicitly instantiate PolicyManager::OnPolicyReadyToEvaluate with the
102 // latter in lieu of the former.
Alex Deymo7b948f02014-03-10 17:01:10 -0700103 base::Closure closure = base::Bind(
Gilad Arnold13a82432014-05-19 12:52:44 -0700104 &PolicyManager::OnPolicyReadyToEvaluate<R, ExpectedArgs...>,
Alex Deymo7b948f02014-03-10 17:01:10 -0700105 base::Unretained(this), ec, callback, policy_method, args...);
106 RunFromMainLoop(closure);
107}
108
Alex Deymoc705cc82014-02-19 11:15:00 -0800109} // namespace chromeos_policy_manager
110
Gilad Arnold2cbb3852014-03-07 12:40:50 -0800111#endif // CHROMEOS_PLATFORM_UPDATE_ENGINE_POLICY_MANAGER_POLICY_MANAGER_INL_H_