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