blob: 732175fe5d5d92f51c15861d932c85433eb23f17 [file] [log] [blame]
Alex Deymoaea4c1c2015-08-19 20:24:43 -07001//
2// Copyright (C) 2014 The Android Open Source Project
3//
4// Licensed under the Apache License, Version 2.0 (the "License");
5// you may not use this file except in compliance with the License.
6// You may obtain a copy of the License at
7//
8// http://www.apache.org/licenses/LICENSE-2.0
9//
10// Unless required by applicable law or agreed to in writing, software
11// distributed under the License is distributed on an "AS IS" BASIS,
12// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13// See the License for the specific language governing permissions and
14// limitations under the License.
15//
Alex Deymoc705cc82014-02-19 11:15:00 -080016
Gilad Arnold48415f12014-06-27 07:10:58 -070017#ifndef UPDATE_ENGINE_UPDATE_MANAGER_UPDATE_MANAGER_H_
18#define UPDATE_ENGINE_UPDATE_MANAGER_UPDATE_MANAGER_H_
19
Ben Chan02f7c1d2014-10-18 15:18:02 -070020#include <memory>
Gilad Arnold83ffdda2014-08-08 13:30:31 -070021#include <set>
Gilad Arnold48415f12014-06-27 07:10:58 -070022#include <string>
Alex Deymoc705cc82014-02-19 11:15:00 -080023
Alex Deymo7b948f02014-03-10 17:01:10 -070024#include <base/callback.h>
25#include <base/memory/ref_counted.h>
Gilad Arnoldb2271992014-06-19 12:35:24 -070026#include <base/time/time.h>
Alex Deymoc705cc82014-02-19 11:15:00 -080027
Alex Deymo39910dc2015-11-09 17:04:30 -080028#include "update_engine/common/clock_interface.h"
Alex Deymo63784a52014-05-28 10:46:14 -070029#include "update_engine/update_manager/default_policy.h"
Gilad Arnold83ffdda2014-08-08 13:30:31 -070030#include "update_engine/update_manager/evaluation_context.h"
Alex Deymo63784a52014-05-28 10:46:14 -070031#include "update_engine/update_manager/policy.h"
32#include "update_engine/update_manager/state.h"
Alex Deymoc705cc82014-02-19 11:15:00 -080033
Alex Deymo63784a52014-05-28 10:46:14 -070034namespace chromeos_update_manager {
Alex Deymoc705cc82014-02-19 11:15:00 -080035
Gilad Arnold83ffdda2014-08-08 13:30:31 -070036// Comparator for scoped_refptr objects.
Amin Hassani4b717432019-01-14 16:24:20 -080037template <typename T>
Gilad Arnold83ffdda2014-08-08 13:30:31 -070038struct ScopedRefPtrLess {
39 bool operator()(const scoped_refptr<T>& first,
40 const scoped_refptr<T>& second) const {
41 return first.get() < second.get();
42 }
43};
44
Jae Hoon Kim504c3cb2019-07-02 11:17:24 -070045// Please do not move this class into a new file for simplicity.
46// This pure virtual class is purely created for purpose of testing. The reason
47// was that |UpdateManager|'s member functions are templatized, which does not
48// play nicely when testing (mocking + faking). Whenever a specialized member of
49// |UpdateManager| must be tested, please add a specialized template member
50// function within this class for testing.
51class SpecializedPolicyRequestInterface {
52 public:
53 virtual ~SpecializedPolicyRequestInterface() = default;
54
55 virtual void AsyncPolicyRequestUpdateCheckAllowed(
56 base::Callback<void(EvalStatus, const UpdateCheckParams& result)>
57 callback,
58 EvalStatus (Policy::*policy_method)(EvaluationContext*,
59 State*,
60 std::string*,
61 UpdateCheckParams*) const) = 0;
62};
63
Alex Deymo63784a52014-05-28 10:46:14 -070064// The main Update Manager singleton class.
Jae Hoon Kim504c3cb2019-07-02 11:17:24 -070065class UpdateManager : public SpecializedPolicyRequestInterface {
Alex Deymoc705cc82014-02-19 11:15:00 -080066 public:
Alex Deymo63784a52014-05-28 10:46:14 -070067 // Creates the UpdateManager instance, assuming ownership on the provided
Alex Deymo680d0222014-04-24 21:00:08 -070068 // |state|.
Alex Deymo63784a52014-05-28 10:46:14 -070069 UpdateManager(chromeos_update_engine::ClockInterface* clock,
Gilad Arnoldfd45a732014-08-07 15:53:46 -070070 base::TimeDelta evaluation_timeout,
Amin Hassani4b717432019-01-14 16:24:20 -080071 base::TimeDelta expiration_timeout,
72 State* state);
Alex Deymoc705cc82014-02-19 11:15:00 -080073
Gilad Arnold83ffdda2014-08-08 13:30:31 -070074 virtual ~UpdateManager();
Alex Deymoc705cc82014-02-19 11:15:00 -080075
76 // PolicyRequest() evaluates the given policy with the provided arguments and
77 // returns the result. The |policy_method| is the pointer-to-method of the
Alex Deymo63784a52014-05-28 10:46:14 -070078 // Policy class for the policy request to call. The UpdateManager will call
Alex Vakulenko88b591f2014-08-28 16:48:57 -070079 // this method on the right policy. The pointer |result| must not be null
80 // and the remaining |args| depend on the arguments required by the passed
Alex Deymoc705cc82014-02-19 11:15:00 -080081 // |policy_method|.
82 //
83 // When the policy request succeeds, the |result| is set and the method
Gilad Arnold897b5e52014-05-21 09:37:18 -070084 // returns EvalStatus::kSucceeded, otherwise, the |result| may not be set. A
85 // policy called with this method should not block (i.e. return
86 // EvalStatus::kAskMeAgainLater), which is considered a programming error. On
87 // failure, EvalStatus::kFailed is returned.
Alex Deymoc705cc82014-02-19 11:15:00 -080088 //
89 // An example call to this method is:
Alex Deymo63784a52014-05-28 10:46:14 -070090 // um.PolicyRequest(&Policy::SomePolicyMethod, &bool_result, arg1, arg2);
Amin Hassani4b717432019-01-14 16:24:20 -080091 template <typename R, typename... ActualArgs, typename... ExpectedArgs>
Alex Deymoe75e0252014-04-08 14:00:11 -070092 EvalStatus PolicyRequest(
Amin Hassani4b717432019-01-14 16:24:20 -080093 EvalStatus (Policy::*policy_method)(
94 EvaluationContext*, State*, std::string*, R*, ExpectedArgs...) const,
95 R* result,
96 ActualArgs...);
Alex Deymoc705cc82014-02-19 11:15:00 -080097
Alex Deymo7b948f02014-03-10 17:01:10 -070098 // Evaluates the given |policy_method| policy with the provided |args|
99 // arguments and calls the |callback| callback with the result when done.
100 //
101 // If the policy implementation should block, returning a
Alex Deymo63784a52014-05-28 10:46:14 -0700102 // EvalStatus::kAskMeAgainLater status the Update Manager will re-evaluate the
Alex Deymo53556ec2014-03-17 10:05:57 -0700103 // policy until another status is returned. If the policy implementation based
104 // its return value solely on const variables, the callback will be called
Gilad Arnoldfd45a732014-08-07 15:53:46 -0700105 // with the EvalStatus::kAskMeAgainLater status (which indicates an error).
Amin Hassani4b717432019-01-14 16:24:20 -0800106 template <typename R, typename... ActualArgs, typename... ExpectedArgs>
Alex Deymo7b948f02014-03-10 17:01:10 -0700107 void AsyncPolicyRequest(
108 base::Callback<void(EvalStatus, const R& result)> callback,
Amin Hassani4b717432019-01-14 16:24:20 -0800109 EvalStatus (Policy::*policy_method)(
110 EvaluationContext*, State*, std::string*, R*, ExpectedArgs...) const,
Gilad Arnold13a82432014-05-19 12:52:44 -0700111 ActualArgs... args);
Alex Deymo7b948f02014-03-10 17:01:10 -0700112
Jae Hoon Kim504c3cb2019-07-02 11:17:24 -0700113 void AsyncPolicyRequestUpdateCheckAllowed(
114 base::Callback<void(EvalStatus, const UpdateCheckParams& result)>
115 callback,
116 EvalStatus (Policy::*policy_method)(EvaluationContext*,
117 State*,
118 std::string*,
119 UpdateCheckParams*) const) override;
120
Alex Deymo94c06162014-03-21 20:34:46 -0700121 protected:
Alex Deymo63784a52014-05-28 10:46:14 -0700122 // The UpdateManager receives ownership of the passed Policy instance.
Amin Hassani4b717432019-01-14 16:24:20 -0800123 void set_policy(const Policy* policy) { policy_.reset(policy); }
Alex Deymo94c06162014-03-21 20:34:46 -0700124
Alex Deymo680d0222014-04-24 21:00:08 -0700125 // State getter used for testing.
126 State* state() { return state_.get(); }
127
Alex Deymoc705cc82014-02-19 11:15:00 -0800128 private:
Alex Deymo63784a52014-05-28 10:46:14 -0700129 FRIEND_TEST(UmUpdateManagerTest, PolicyRequestCallsPolicy);
130 FRIEND_TEST(UmUpdateManagerTest, PolicyRequestCallsDefaultOnError);
Gilad Arnold897b5e52014-05-21 09:37:18 -0700131 FRIEND_TEST(UmUpdateManagerTest, PolicyRequestDoesntBlockDeathTest);
Alex Deymo63784a52014-05-28 10:46:14 -0700132 FRIEND_TEST(UmUpdateManagerTest, AsyncPolicyRequestDelaysEvaluation);
Gilad Arnoldfd45a732014-08-07 15:53:46 -0700133 FRIEND_TEST(UmUpdateManagerTest, AsyncPolicyRequestTimeoutDoesNotFire);
Gilad Arnoldf9f85d62014-06-19 18:07:01 -0700134 FRIEND_TEST(UmUpdateManagerTest, AsyncPolicyRequestTimesOut);
Alex Deymo7b948f02014-03-10 17:01:10 -0700135
Alex Deymo7b948f02014-03-10 17:01:10 -0700136 // EvaluatePolicy() evaluates the passed |policy_method| method on the current
137 // policy with the given |args| arguments. If the method fails, the default
138 // policy is used instead.
Amin Hassani4b717432019-01-14 16:24:20 -0800139 template <typename R, typename... Args>
Alex Deymoe75e0252014-04-08 14:00:11 -0700140 EvalStatus EvaluatePolicy(
141 EvaluationContext* ec,
Amin Hassani4b717432019-01-14 16:24:20 -0800142 EvalStatus (Policy::*policy_method)(
143 EvaluationContext*, State*, std::string*, R*, Args...) const,
144 R* result,
145 Args... args);
Alex Deymo7b948f02014-03-10 17:01:10 -0700146
147 // OnPolicyReadyToEvaluate() is called by the main loop when the evaluation
148 // of the given |policy_method| should be executed. If the evaluation finishes
149 // the |callback| callback is called passing the |result| and the |status|
150 // returned by the policy. If the evaluation returns an
151 // EvalStatus::kAskMeAgainLater state, the |callback| will NOT be called and
152 // the evaluation will be re-scheduled to be called later.
Amin Hassani4b717432019-01-14 16:24:20 -0800153 template <typename R, typename... Args>
Alex Deymo7b948f02014-03-10 17:01:10 -0700154 void OnPolicyReadyToEvaluate(
155 scoped_refptr<EvaluationContext> ec,
156 base::Callback<void(EvalStatus status, const R& result)> callback,
Amin Hassani4b717432019-01-14 16:24:20 -0800157 EvalStatus (Policy::*policy_method)(
158 EvaluationContext*, State*, std::string*, R*, Args...) const,
Alex Deymoe75e0252014-04-08 14:00:11 -0700159 Args... args);
Alex Deymoc705cc82014-02-19 11:15:00 -0800160
Gilad Arnold83ffdda2014-08-08 13:30:31 -0700161 // Unregisters (removes from repo) a previously created EvaluationContext.
162 void UnregisterEvalContext(EvaluationContext* ec);
163
Alex Deymo63784a52014-05-28 10:46:14 -0700164 // The policy used by the UpdateManager. Note that since it is a const Policy,
Alex Deymoc705cc82014-02-19 11:15:00 -0800165 // policy implementations are not allowed to persist state on this class.
Ben Chan02f7c1d2014-10-18 15:18:02 -0700166 std::unique_ptr<const Policy> policy_;
Alex Deymoc705cc82014-02-19 11:15:00 -0800167
168 // A safe default value to the current policy. This policy is used whenever
Alex Deymoe636c3c2014-03-11 19:02:08 -0700169 // a policy implementation fails with EvalStatus::kFailed.
Alex Deymoc705cc82014-02-19 11:15:00 -0800170 const DefaultPolicy default_policy_;
171
Alex Deymo2de23f52014-02-26 14:30:13 -0800172 // State Providers.
Ben Chan02f7c1d2014-10-18 15:18:02 -0700173 std::unique_ptr<State> state_;
Alex Deymoc705cc82014-02-19 11:15:00 -0800174
Alex Deymo41a75a72014-04-15 15:36:22 -0700175 // Pointer to the mockable clock interface;
176 chromeos_update_engine::ClockInterface* clock_;
177
Gilad Arnoldb2271992014-06-19 12:35:24 -0700178 // Timeout for a policy evaluation.
179 const base::TimeDelta evaluation_timeout_;
180
Gilad Arnoldfd45a732014-08-07 15:53:46 -0700181 // Timeout for expiration of the evaluation context, used for async requests.
182 const base::TimeDelta expiration_timeout_;
183
Gilad Arnold83ffdda2014-08-08 13:30:31 -0700184 // Repository of previously created EvaluationContext objects. These are being
185 // unregistered (and the reference released) when the context is being
186 // destructed; alternatively, when the UpdateManager instance is destroyed, it
187 // will remove all pending events associated with all outstanding contexts
188 // (which should, in turn, trigger their destruction).
189 std::set<scoped_refptr<EvaluationContext>,
Amin Hassani4b717432019-01-14 16:24:20 -0800190 ScopedRefPtrLess<EvaluationContext>>
191 ec_repo_;
Gilad Arnold83ffdda2014-08-08 13:30:31 -0700192
193 base::WeakPtrFactory<UpdateManager> weak_ptr_factory_;
194
Alex Deymo63784a52014-05-28 10:46:14 -0700195 DISALLOW_COPY_AND_ASSIGN(UpdateManager);
Alex Deymoc705cc82014-02-19 11:15:00 -0800196};
197
Alex Deymo63784a52014-05-28 10:46:14 -0700198} // namespace chromeos_update_manager
Alex Deymoc705cc82014-02-19 11:15:00 -0800199
200// Include the implementation of the template methods.
Alex Deymo63784a52014-05-28 10:46:14 -0700201#include "update_engine/update_manager/update_manager-inl.h"
Alex Deymoc705cc82014-02-19 11:15:00 -0800202
Gilad Arnold48415f12014-06-27 07:10:58 -0700203#endif // UPDATE_ENGINE_UPDATE_MANAGER_UPDATE_MANAGER_H_