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