blob: 8cfd8f41a0a4c422635bc016bfc452fc2bf1abaf [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 Arnold48415f12014-06-27 07:10:58 -07005#ifndef UPDATE_ENGINE_UPDATE_MANAGER_UPDATE_MANAGER_H_
6#define UPDATE_ENGINE_UPDATE_MANAGER_UPDATE_MANAGER_H_
7
Gilad Arnold83ffdda2014-08-08 13:30:31 -07008#include <set>
Gilad Arnold48415f12014-06-27 07:10:58 -07009#include <string>
Alex Deymoc705cc82014-02-19 11:15:00 -080010
Alex Deymo7b948f02014-03-10 17:01:10 -070011#include <base/callback.h>
12#include <base/memory/ref_counted.h>
Alex Deymoc705cc82014-02-19 11:15:00 -080013#include <base/memory/scoped_ptr.h>
Gilad Arnoldb2271992014-06-19 12:35:24 -070014#include <base/time/time.h>
Alex Deymoc705cc82014-02-19 11:15:00 -080015
Alex Deymo41a75a72014-04-15 15:36:22 -070016#include "update_engine/clock_interface.h"
Alex Deymo63784a52014-05-28 10:46:14 -070017#include "update_engine/update_manager/default_policy.h"
Gilad Arnold83ffdda2014-08-08 13:30:31 -070018#include "update_engine/update_manager/evaluation_context.h"
Alex Deymo63784a52014-05-28 10:46:14 -070019#include "update_engine/update_manager/policy.h"
20#include "update_engine/update_manager/state.h"
Alex Deymoc705cc82014-02-19 11:15:00 -080021
Alex Deymo63784a52014-05-28 10:46:14 -070022namespace chromeos_update_manager {
Alex Deymoc705cc82014-02-19 11:15:00 -080023
Gilad Arnold83ffdda2014-08-08 13:30:31 -070024// Comparator for scoped_refptr objects.
25template<typename T>
26struct ScopedRefPtrLess {
27 bool operator()(const scoped_refptr<T>& first,
28 const scoped_refptr<T>& second) const {
29 return first.get() < second.get();
30 }
31};
32
Alex Deymo63784a52014-05-28 10:46:14 -070033// The main Update Manager singleton class.
34class UpdateManager {
Alex Deymoc705cc82014-02-19 11:15:00 -080035 public:
Alex Deymo63784a52014-05-28 10:46:14 -070036 // Creates the UpdateManager instance, assuming ownership on the provided
Alex Deymo680d0222014-04-24 21:00:08 -070037 // |state|.
Alex Deymo63784a52014-05-28 10:46:14 -070038 UpdateManager(chromeos_update_engine::ClockInterface* clock,
Gilad Arnoldfd45a732014-08-07 15:53:46 -070039 base::TimeDelta evaluation_timeout,
40 base::TimeDelta expiration_timeout, State* state);
Alex Deymoc705cc82014-02-19 11:15:00 -080041
Gilad Arnold83ffdda2014-08-08 13:30:31 -070042 virtual ~UpdateManager();
Alex Deymoc705cc82014-02-19 11:15:00 -080043
44 // PolicyRequest() evaluates the given policy with the provided arguments and
45 // returns the result. The |policy_method| is the pointer-to-method of the
Alex Deymo63784a52014-05-28 10:46:14 -070046 // Policy class for the policy request to call. The UpdateManager will call
Alex Deymoc705cc82014-02-19 11:15:00 -080047 // this method on the right policy. The pointer |result| must not be NULL and
48 // the remaining |args| depend on the arguments required by the passed
49 // |policy_method|.
50 //
51 // When the policy request succeeds, the |result| is set and the method
Gilad Arnold897b5e52014-05-21 09:37:18 -070052 // returns EvalStatus::kSucceeded, otherwise, the |result| may not be set. A
53 // policy called with this method should not block (i.e. return
54 // EvalStatus::kAskMeAgainLater), which is considered a programming error. On
55 // failure, EvalStatus::kFailed is returned.
Alex Deymoc705cc82014-02-19 11:15:00 -080056 //
57 // An example call to this method is:
Alex Deymo63784a52014-05-28 10:46:14 -070058 // um.PolicyRequest(&Policy::SomePolicyMethod, &bool_result, arg1, arg2);
Gilad Arnold13a82432014-05-19 12:52:44 -070059 template<typename R, typename... ActualArgs, typename... ExpectedArgs>
Alex Deymoe75e0252014-04-08 14:00:11 -070060 EvalStatus PolicyRequest(
Gilad Arnold13a82432014-05-19 12:52:44 -070061 EvalStatus (Policy::*policy_method)(EvaluationContext*, State*,
62 std::string*, R*,
63 ExpectedArgs...) const,
64 R* result, ActualArgs...);
Alex Deymoc705cc82014-02-19 11:15:00 -080065
Alex Deymo7b948f02014-03-10 17:01:10 -070066 // Evaluates the given |policy_method| policy with the provided |args|
67 // arguments and calls the |callback| callback with the result when done.
68 //
69 // If the policy implementation should block, returning a
Alex Deymo63784a52014-05-28 10:46:14 -070070 // EvalStatus::kAskMeAgainLater status the Update Manager will re-evaluate the
Alex Deymo53556ec2014-03-17 10:05:57 -070071 // policy until another status is returned. If the policy implementation based
72 // its return value solely on const variables, the callback will be called
Gilad Arnoldfd45a732014-08-07 15:53:46 -070073 // with the EvalStatus::kAskMeAgainLater status (which indicates an error).
Gilad Arnold13a82432014-05-19 12:52:44 -070074 template<typename R, typename... ActualArgs, typename... ExpectedArgs>
Alex Deymo7b948f02014-03-10 17:01:10 -070075 void AsyncPolicyRequest(
76 base::Callback<void(EvalStatus, const R& result)> callback,
Gilad Arnold13a82432014-05-19 12:52:44 -070077 EvalStatus (Policy::*policy_method)(EvaluationContext*, State*,
78 std::string*, R*,
79 ExpectedArgs...) const,
80 ActualArgs... args);
Alex Deymo7b948f02014-03-10 17:01:10 -070081
Alex Deymo94c06162014-03-21 20:34:46 -070082 protected:
Alex Deymo63784a52014-05-28 10:46:14 -070083 // The UpdateManager receives ownership of the passed Policy instance.
Alex Deymo94c06162014-03-21 20:34:46 -070084 void set_policy(const Policy* policy) {
85 policy_.reset(policy);
86 }
87
Alex Deymo680d0222014-04-24 21:00:08 -070088 // State getter used for testing.
89 State* state() { return state_.get(); }
90
Alex Deymoc705cc82014-02-19 11:15:00 -080091 private:
Alex Deymo63784a52014-05-28 10:46:14 -070092 FRIEND_TEST(UmUpdateManagerTest, PolicyRequestCallsPolicy);
93 FRIEND_TEST(UmUpdateManagerTest, PolicyRequestCallsDefaultOnError);
Gilad Arnold897b5e52014-05-21 09:37:18 -070094 FRIEND_TEST(UmUpdateManagerTest, PolicyRequestDoesntBlockDeathTest);
Alex Deymo63784a52014-05-28 10:46:14 -070095 FRIEND_TEST(UmUpdateManagerTest, AsyncPolicyRequestDelaysEvaluation);
Gilad Arnoldfd45a732014-08-07 15:53:46 -070096 FRIEND_TEST(UmUpdateManagerTest, AsyncPolicyRequestTimeoutDoesNotFire);
Gilad Arnoldf9f85d62014-06-19 18:07:01 -070097 FRIEND_TEST(UmUpdateManagerTest, AsyncPolicyRequestTimesOut);
Alex Deymo7b948f02014-03-10 17:01:10 -070098
Alex Deymo7b948f02014-03-10 17:01:10 -070099 // EvaluatePolicy() evaluates the passed |policy_method| method on the current
100 // policy with the given |args| arguments. If the method fails, the default
101 // policy is used instead.
Alex Deymoe75e0252014-04-08 14:00:11 -0700102 template<typename R, typename... Args>
103 EvalStatus EvaluatePolicy(
104 EvaluationContext* ec,
Gilad Arnold13a82432014-05-19 12:52:44 -0700105 EvalStatus (Policy::*policy_method)(EvaluationContext*, State*,
106 std::string*, R*,
107 Args...) const,
Alex Deymoe75e0252014-04-08 14:00:11 -0700108 R* result, Args... args);
Alex Deymo7b948f02014-03-10 17:01:10 -0700109
110 // OnPolicyReadyToEvaluate() is called by the main loop when the evaluation
111 // of the given |policy_method| should be executed. If the evaluation finishes
112 // the |callback| callback is called passing the |result| and the |status|
113 // returned by the policy. If the evaluation returns an
114 // EvalStatus::kAskMeAgainLater state, the |callback| will NOT be called and
115 // the evaluation will be re-scheduled to be called later.
Alex Deymoe75e0252014-04-08 14:00:11 -0700116 template<typename R, typename... Args>
Alex Deymo7b948f02014-03-10 17:01:10 -0700117 void OnPolicyReadyToEvaluate(
118 scoped_refptr<EvaluationContext> ec,
119 base::Callback<void(EvalStatus status, const R& result)> callback,
Gilad Arnold13a82432014-05-19 12:52:44 -0700120 EvalStatus (Policy::*policy_method)(EvaluationContext*, State*,
121 std::string*, R*,
122 Args...) const,
Alex Deymoe75e0252014-04-08 14:00:11 -0700123 Args... args);
Alex Deymoc705cc82014-02-19 11:15:00 -0800124
Gilad Arnold83ffdda2014-08-08 13:30:31 -0700125 // Unregisters (removes from repo) a previously created EvaluationContext.
126 void UnregisterEvalContext(EvaluationContext* ec);
127
Alex Deymo63784a52014-05-28 10:46:14 -0700128 // The policy used by the UpdateManager. Note that since it is a const Policy,
Alex Deymoc705cc82014-02-19 11:15:00 -0800129 // policy implementations are not allowed to persist state on this class.
130 scoped_ptr<const Policy> policy_;
131
132 // A safe default value to the current policy. This policy is used whenever
Alex Deymoe636c3c2014-03-11 19:02:08 -0700133 // a policy implementation fails with EvalStatus::kFailed.
Alex Deymoc705cc82014-02-19 11:15:00 -0800134 const DefaultPolicy default_policy_;
135
Alex Deymo2de23f52014-02-26 14:30:13 -0800136 // State Providers.
137 scoped_ptr<State> state_;
Alex Deymoc705cc82014-02-19 11:15:00 -0800138
Alex Deymo41a75a72014-04-15 15:36:22 -0700139 // Pointer to the mockable clock interface;
140 chromeos_update_engine::ClockInterface* clock_;
141
Gilad Arnoldb2271992014-06-19 12:35:24 -0700142 // Timeout for a policy evaluation.
143 const base::TimeDelta evaluation_timeout_;
144
Gilad Arnoldfd45a732014-08-07 15:53:46 -0700145 // Timeout for expiration of the evaluation context, used for async requests.
146 const base::TimeDelta expiration_timeout_;
147
Gilad Arnold83ffdda2014-08-08 13:30:31 -0700148 // Repository of previously created EvaluationContext objects. These are being
149 // unregistered (and the reference released) when the context is being
150 // destructed; alternatively, when the UpdateManager instance is destroyed, it
151 // will remove all pending events associated with all outstanding contexts
152 // (which should, in turn, trigger their destruction).
153 std::set<scoped_refptr<EvaluationContext>,
154 ScopedRefPtrLess<EvaluationContext>> ec_repo_;
155
156 base::WeakPtrFactory<UpdateManager> weak_ptr_factory_;
157
Alex Deymo63784a52014-05-28 10:46:14 -0700158 DISALLOW_COPY_AND_ASSIGN(UpdateManager);
Alex Deymoc705cc82014-02-19 11:15:00 -0800159};
160
Alex Deymo63784a52014-05-28 10:46:14 -0700161} // namespace chromeos_update_manager
Alex Deymoc705cc82014-02-19 11:15:00 -0800162
163// Include the implementation of the template methods.
Alex Deymo63784a52014-05-28 10:46:14 -0700164#include "update_engine/update_manager/update_manager-inl.h"
Alex Deymoc705cc82014-02-19 11:15:00 -0800165
Gilad Arnold48415f12014-06-27 07:10:58 -0700166#endif // UPDATE_ENGINE_UPDATE_MANAGER_UPDATE_MANAGER_H_