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