1 // 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 // 16 17 #ifndef UPDATE_ENGINE_UPDATE_MANAGER_UPDATE_MANAGER_H_ 18 #define UPDATE_ENGINE_UPDATE_MANAGER_UPDATE_MANAGER_H_ 19 20 #include <memory> 21 #include <set> 22 #include <string> 23 24 #include <base/callback.h> 25 #include <base/memory/ref_counted.h> 26 #include <base/time/time.h> 27 28 #include "update_engine/common/clock_interface.h" 29 #include "update_engine/update_manager/default_policy.h" 30 #include "update_engine/update_manager/evaluation_context.h" 31 #include "update_engine/update_manager/policy.h" 32 #include "update_engine/update_manager/state.h" 33 34 namespace chromeos_update_manager { 35 36 // Comparator for scoped_refptr objects. 37 template <typename T> 38 struct ScopedRefPtrLess { operatorScopedRefPtrLess39 bool operator()(const scoped_refptr<T>& first, 40 const scoped_refptr<T>& second) const { 41 return first.get() < second.get(); 42 } 43 }; 44 45 // The main Update Manager singleton class. 46 class UpdateManager { 47 public: 48 // Creates the UpdateManager instance, assuming ownership on the provided 49 // |state|. 50 UpdateManager(chromeos_update_engine::ClockInterface* clock, 51 base::TimeDelta evaluation_timeout, 52 base::TimeDelta expiration_timeout, 53 State* state); 54 55 virtual ~UpdateManager(); 56 57 // PolicyRequest() evaluates the given policy with the provided arguments and 58 // returns the result. The |policy_method| is the pointer-to-method of the 59 // Policy class for the policy request to call. The UpdateManager will call 60 // this method on the right policy. The pointer |result| must not be null 61 // and the remaining |args| depend on the arguments required by the passed 62 // |policy_method|. 63 // 64 // When the policy request succeeds, the |result| is set and the method 65 // returns EvalStatus::kSucceeded, otherwise, the |result| may not be set. A 66 // policy called with this method should not block (i.e. return 67 // EvalStatus::kAskMeAgainLater), which is considered a programming error. On 68 // failure, EvalStatus::kFailed is returned. 69 // 70 // An example call to this method is: 71 // um.PolicyRequest(&Policy::SomePolicyMethod, &bool_result, arg1, arg2); 72 template <typename R, typename... ActualArgs, typename... ExpectedArgs> 73 EvalStatus PolicyRequest( 74 EvalStatus (Policy::*policy_method)( 75 EvaluationContext*, State*, std::string*, R*, ExpectedArgs...) const, 76 R* result, 77 ActualArgs...); 78 79 // Evaluates the given |policy_method| policy with the provided |args| 80 // arguments and calls the |callback| callback with the result when done. 81 // 82 // If the policy implementation should block, returning a 83 // EvalStatus::kAskMeAgainLater status the Update Manager will re-evaluate the 84 // policy until another status is returned. If the policy implementation based 85 // its return value solely on const variables, the callback will be called 86 // with the EvalStatus::kAskMeAgainLater status (which indicates an error). 87 template <typename R, typename... ActualArgs, typename... ExpectedArgs> 88 void AsyncPolicyRequest( 89 base::Callback<void(EvalStatus, const R& result)> callback, 90 EvalStatus (Policy::*policy_method)( 91 EvaluationContext*, State*, std::string*, R*, ExpectedArgs...) const, 92 ActualArgs... args); 93 94 protected: 95 // The UpdateManager receives ownership of the passed Policy instance. set_policy(const Policy * policy)96 void set_policy(const Policy* policy) { policy_.reset(policy); } 97 98 // State getter used for testing. state()99 State* state() { return state_.get(); } 100 101 private: 102 FRIEND_TEST(UmUpdateManagerTest, PolicyRequestCallsPolicy); 103 FRIEND_TEST(UmUpdateManagerTest, PolicyRequestCallsDefaultOnError); 104 FRIEND_TEST(UmUpdateManagerTest, PolicyRequestDoesntBlockDeathTest); 105 FRIEND_TEST(UmUpdateManagerTest, AsyncPolicyRequestDelaysEvaluation); 106 FRIEND_TEST(UmUpdateManagerTest, AsyncPolicyRequestTimeoutDoesNotFire); 107 FRIEND_TEST(UmUpdateManagerTest, AsyncPolicyRequestTimesOut); 108 109 // EvaluatePolicy() evaluates the passed |policy_method| method on the current 110 // policy with the given |args| arguments. If the method fails, the default 111 // policy is used instead. 112 template <typename R, typename... Args> 113 EvalStatus EvaluatePolicy( 114 EvaluationContext* ec, 115 EvalStatus (Policy::*policy_method)( 116 EvaluationContext*, State*, std::string*, R*, Args...) const, 117 R* result, 118 Args... args); 119 120 // OnPolicyReadyToEvaluate() is called by the main loop when the evaluation 121 // of the given |policy_method| should be executed. If the evaluation finishes 122 // the |callback| callback is called passing the |result| and the |status| 123 // returned by the policy. If the evaluation returns an 124 // EvalStatus::kAskMeAgainLater state, the |callback| will NOT be called and 125 // the evaluation will be re-scheduled to be called later. 126 template <typename R, typename... Args> 127 void OnPolicyReadyToEvaluate( 128 scoped_refptr<EvaluationContext> ec, 129 base::Callback<void(EvalStatus status, const R& result)> callback, 130 EvalStatus (Policy::*policy_method)( 131 EvaluationContext*, State*, std::string*, R*, Args...) const, 132 Args... args); 133 134 // Unregisters (removes from repo) a previously created EvaluationContext. 135 void UnregisterEvalContext(EvaluationContext* ec); 136 137 // The policy used by the UpdateManager. Note that since it is a const Policy, 138 // policy implementations are not allowed to persist state on this class. 139 std::unique_ptr<const Policy> policy_; 140 141 // A safe default value to the current policy. This policy is used whenever 142 // a policy implementation fails with EvalStatus::kFailed. 143 const DefaultPolicy default_policy_; 144 145 // State Providers. 146 std::unique_ptr<State> state_; 147 148 // Pointer to the mockable clock interface; 149 chromeos_update_engine::ClockInterface* clock_; 150 151 // Timeout for a policy evaluation. 152 const base::TimeDelta evaluation_timeout_; 153 154 // Timeout for expiration of the evaluation context, used for async requests. 155 const base::TimeDelta expiration_timeout_; 156 157 // Repository of previously created EvaluationContext objects. These are being 158 // unregistered (and the reference released) when the context is being 159 // destructed; alternatively, when the UpdateManager instance is destroyed, it 160 // will remove all pending events associated with all outstanding contexts 161 // (which should, in turn, trigger their destruction). 162 std::set<scoped_refptr<EvaluationContext>, 163 ScopedRefPtrLess<EvaluationContext>> 164 ec_repo_; 165 166 base::WeakPtrFactory<UpdateManager> weak_ptr_factory_; 167 168 DISALLOW_COPY_AND_ASSIGN(UpdateManager); 169 }; 170 171 } // namespace chromeos_update_manager 172 173 // Include the implementation of the template methods. 174 #include "update_engine/update_manager/update_manager-inl.h" 175 176 #endif // UPDATE_ENGINE_UPDATE_MANAGER_UPDATE_MANAGER_H_ 177