1aea4c1cea20dda7ae7e85fc8924a2d784f70d806Alex Deymo// 2aea4c1cea20dda7ae7e85fc8924a2d784f70d806Alex Deymo// Copyright (C) 2014 The Android Open Source Project 3aea4c1cea20dda7ae7e85fc8924a2d784f70d806Alex Deymo// 4aea4c1cea20dda7ae7e85fc8924a2d784f70d806Alex Deymo// Licensed under the Apache License, Version 2.0 (the "License"); 5aea4c1cea20dda7ae7e85fc8924a2d784f70d806Alex Deymo// you may not use this file except in compliance with the License. 6aea4c1cea20dda7ae7e85fc8924a2d784f70d806Alex Deymo// You may obtain a copy of the License at 7aea4c1cea20dda7ae7e85fc8924a2d784f70d806Alex Deymo// 8aea4c1cea20dda7ae7e85fc8924a2d784f70d806Alex Deymo// http://www.apache.org/licenses/LICENSE-2.0 9aea4c1cea20dda7ae7e85fc8924a2d784f70d806Alex Deymo// 10aea4c1cea20dda7ae7e85fc8924a2d784f70d806Alex Deymo// Unless required by applicable law or agreed to in writing, software 11aea4c1cea20dda7ae7e85fc8924a2d784f70d806Alex Deymo// distributed under the License is distributed on an "AS IS" BASIS, 12aea4c1cea20dda7ae7e85fc8924a2d784f70d806Alex Deymo// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13aea4c1cea20dda7ae7e85fc8924a2d784f70d806Alex Deymo// See the License for the specific language governing permissions and 14aea4c1cea20dda7ae7e85fc8924a2d784f70d806Alex Deymo// limitations under the License. 15aea4c1cea20dda7ae7e85fc8924a2d784f70d806Alex Deymo// 1623949d4e086ca984ca2ce07efb6d4ae2bc5daf42Alex Deymo 1763784a578dd26880454d70797519358a2326291bAlex Deymo#include "update_engine/update_manager/evaluation_context.h" 1823949d4e086ca984ca2ce07efb6d4ae2bc5daf42Alex Deymo 19f9f85d6680164064648ce3ed1d31589e1f1b7a29Gilad Arnold#include <algorithm> 2002f7c1dee242f490143791dbb73fa23fa3007cfaBen Chan#include <memory> 21c14902888be0b8d41759e6ff0a7100af4097fd09David Zeuthen#include <string> 22067053eea5711adb79307f290f05fd0a876be0ebBen Chan#include <utility> 23c14902888be0b8d41759e6ff0a7100af4097fd09David Zeuthen 2453556eccd206bacd5c9c8bb6605bcceb1bcb6190Alex Deymo#include <base/bind.h> 25c14902888be0b8d41759e6ff0a7100af4097fd09David Zeuthen#include <base/json/json_writer.h> 260bb234147ea8f0247b733375fcf1685eaf329aacAlex Deymo#include <base/location.h> 27067053eea5711adb79307f290f05fd0a876be0ebBen Chan#include <base/memory/ptr_util.h> 286e5ab5c011a214aa345ecbba3d910c2ffaec3c83Gilad Arnold#include <base/strings/string_util.h> 29c14902888be0b8d41759e6ff0a7100af4097fd09David Zeuthen#include <base/values.h> 30c14902888be0b8d41759e6ff0a7100af4097fd09David Zeuthen 3139910dcd1d68987ccee7c3031dc269233a8490bbAlex Deymo#include "update_engine/common/utils.h" 3253556eccd206bacd5c9c8bb6605bcceb1bcb6190Alex Deymo 3383ffddaa3b09ceb4361e5c01ba300d57ab697a7eGilad Arnoldusing base::Callback; 3453556eccd206bacd5c9c8bb6605bcceb1bcb6190Alex Deymousing base::Closure; 3541a75a7ca3f0252f2c9f991dd465aa332e7ce4d1Alex Deymousing base::Time; 3623949d4e086ca984ca2ce07efb6d4ae2bc5daf42Alex Deymousing base::TimeDelta; 373f39d5cc753905874d8d93bef94f857b8808f19eAlex Vakulenkousing brillo::MessageLoop; 3841a75a7ca3f0252f2c9f991dd465aa332e7ce4d1Alex Deymousing chromeos_update_engine::ClockInterface; 39c14902888be0b8d41759e6ff0a7100af4097fd09David Zeuthenusing std::string; 4002f7c1dee242f490143791dbb73fa23fa3007cfaBen Chanusing std::unique_ptr; 4123949d4e086ca984ca2ce07efb6d4ae2bc5daf42Alex Deymo 42a65fced5f4c2b551616b26ee90a800b44090735fGilad Arnoldnamespace { 43a65fced5f4c2b551616b26ee90a800b44090735fGilad Arnold 44a65fced5f4c2b551616b26ee90a800b44090735fGilad Arnold// Returns whether |curr_time| surpassed |ref_time|; if not, also checks whether 45a65fced5f4c2b551616b26ee90a800b44090735fGilad Arnold// |ref_time| is sooner than the current value of |*reeval_time|, in which case 46a65fced5f4c2b551616b26ee90a800b44090735fGilad Arnold// the latter is updated to the former. 47f329b933db41d26644a97afef928eb1b319d6d99Alex Deymobool IsTimeGreaterThanHelper(Time ref_time, Time curr_time, 48f329b933db41d26644a97afef928eb1b319d6d99Alex Deymo Time* reeval_time) { 49a65fced5f4c2b551616b26ee90a800b44090735fGilad Arnold if (curr_time > ref_time) 50a65fced5f4c2b551616b26ee90a800b44090735fGilad Arnold return true; 51a65fced5f4c2b551616b26ee90a800b44090735fGilad Arnold // Remember the nearest reference we've checked against in this evaluation. 52a65fced5f4c2b551616b26ee90a800b44090735fGilad Arnold if (*reeval_time > ref_time) 53a65fced5f4c2b551616b26ee90a800b44090735fGilad Arnold *reeval_time = ref_time; 54a65fced5f4c2b551616b26ee90a800b44090735fGilad Arnold return false; 55a65fced5f4c2b551616b26ee90a800b44090735fGilad Arnold} 56a65fced5f4c2b551616b26ee90a800b44090735fGilad Arnold 57a65fced5f4c2b551616b26ee90a800b44090735fGilad Arnold// If |expires| never happens (maximal value), returns the maximal interval; 58a65fced5f4c2b551616b26ee90a800b44090735fGilad Arnold// otherwise, returns the difference between |expires| and |curr|. 59f329b933db41d26644a97afef928eb1b319d6d99Alex DeymoTimeDelta GetTimeout(Time curr, Time expires) { 60a65fced5f4c2b551616b26ee90a800b44090735fGilad Arnold if (expires.is_max()) 61a65fced5f4c2b551616b26ee90a800b44090735fGilad Arnold return TimeDelta::Max(); 62a65fced5f4c2b551616b26ee90a800b44090735fGilad Arnold return expires - curr; 63a65fced5f4c2b551616b26ee90a800b44090735fGilad Arnold} 64a65fced5f4c2b551616b26ee90a800b44090735fGilad Arnold 65a65fced5f4c2b551616b26ee90a800b44090735fGilad Arnold} // namespace 66a65fced5f4c2b551616b26ee90a800b44090735fGilad Arnold 6763784a578dd26880454d70797519358a2326291bAlex Deymonamespace chromeos_update_manager { 6823949d4e086ca984ca2ce07efb6d4ae2bc5daf42Alex Deymo 6983ffddaa3b09ceb4361e5c01ba300d57ab697a7eGilad ArnoldEvaluationContext::EvaluationContext( 7083ffddaa3b09ceb4361e5c01ba300d57ab697a7eGilad Arnold ClockInterface* clock, 7183ffddaa3b09ceb4361e5c01ba300d57ab697a7eGilad Arnold TimeDelta evaluation_timeout, 7283ffddaa3b09ceb4361e5c01ba300d57ab697a7eGilad Arnold TimeDelta expiration_timeout, 7302f7c1dee242f490143791dbb73fa23fa3007cfaBen Chan unique_ptr<Callback<void(EvaluationContext*)>> unregister_cb) 7441a75a7ca3f0252f2c9f991dd465aa332e7ce4d1Alex Deymo : clock_(clock), 75b227199133f2d694414293697c67599a761f23beGilad Arnold evaluation_timeout_(evaluation_timeout), 76fd45a731d9f9176ce134b34e2a84acc0cf403d1dGilad Arnold expiration_timeout_(expiration_timeout), 7702f7c1dee242f490143791dbb73fa23fa3007cfaBen Chan unregister_cb_(std::move(unregister_cb)), 7841a75a7ca3f0252f2c9f991dd465aa332e7ce4d1Alex Deymo weak_ptr_factory_(this) { 7941a75a7ca3f0252f2c9f991dd465aa332e7ce4d1Alex Deymo ResetEvaluation(); 80fd45a731d9f9176ce134b34e2a84acc0cf403d1dGilad Arnold ResetExpiration(); 8141a75a7ca3f0252f2c9f991dd465aa332e7ce4d1Alex Deymo} 8241a75a7ca3f0252f2c9f991dd465aa332e7ce4d1Alex Deymo 8353556eccd206bacd5c9c8bb6605bcceb1bcb6190Alex DeymoEvaluationContext::~EvaluationContext() { 8453556eccd206bacd5c9c8bb6605bcceb1bcb6190Alex Deymo RemoveObserversAndTimeout(); 8583ffddaa3b09ceb4361e5c01ba300d57ab697a7eGilad Arnold if (unregister_cb_.get()) 8683ffddaa3b09ceb4361e5c01ba300d57ab697a7eGilad Arnold unregister_cb_->Run(this); 8753556eccd206bacd5c9c8bb6605bcceb1bcb6190Alex Deymo} 8853556eccd206bacd5c9c8bb6605bcceb1bcb6190Alex Deymo 8902f7c1dee242f490143791dbb73fa23fa3007cfaBen Chanunique_ptr<Closure> EvaluationContext::RemoveObserversAndTimeout() { 9053556eccd206bacd5c9c8bb6605bcceb1bcb6190Alex Deymo for (auto& it : value_cache_) { 9153556eccd206bacd5c9c8bb6605bcceb1bcb6190Alex Deymo if (it.first->GetMode() == kVariableModeAsync) 9253556eccd206bacd5c9c8bb6605bcceb1bcb6190Alex Deymo it.first->RemoveObserver(this); 9353556eccd206bacd5c9c8bb6605bcceb1bcb6190Alex Deymo } 94509dd5376f47e38d18fe7d29da776e3dc9a9786dAlex Deymo MessageLoop::current()->CancelTask(timeout_event_); 95509dd5376f47e38d18fe7d29da776e3dc9a9786dAlex Deymo timeout_event_ = MessageLoop::kTaskIdNull; 9683ffddaa3b09ceb4361e5c01ba300d57ab697a7eGilad Arnold 97ce8c8ee8f9df9bea3b5aedf930dfeba5da46031cAlex Vakulenko return std::move(callback_); 9853556eccd206bacd5c9c8bb6605bcceb1bcb6190Alex Deymo} 9953556eccd206bacd5c9c8bb6605bcceb1bcb6190Alex Deymo 100f9f85d6680164064648ce3ed1d31589e1f1b7a29Gilad ArnoldTimeDelta EvaluationContext::RemainingTime(Time monotonic_deadline) const { 101f9f85d6680164064648ce3ed1d31589e1f1b7a29Gilad Arnold if (monotonic_deadline.is_max()) 102f9f85d6680164064648ce3ed1d31589e1f1b7a29Gilad Arnold return TimeDelta::Max(); 103f9f85d6680164064648ce3ed1d31589e1f1b7a29Gilad Arnold TimeDelta remaining = monotonic_deadline - clock_->GetMonotonicTime(); 104f9f85d6680164064648ce3ed1d31589e1f1b7a29Gilad Arnold return std::max(remaining, TimeDelta()); 105f9f85d6680164064648ce3ed1d31589e1f1b7a29Gilad Arnold} 106f9f85d6680164064648ce3ed1d31589e1f1b7a29Gilad Arnold 107f9f85d6680164064648ce3ed1d31589e1f1b7a29Gilad ArnoldTime EvaluationContext::MonotonicDeadline(TimeDelta timeout) { 108f9f85d6680164064648ce3ed1d31589e1f1b7a29Gilad Arnold return (timeout.is_max() ? Time::Max() : 109f9f85d6680164064648ce3ed1d31589e1f1b7a29Gilad Arnold clock_->GetMonotonicTime() + timeout); 11023949d4e086ca984ca2ce07efb6d4ae2bc5daf42Alex Deymo} 11123949d4e086ca984ca2ce07efb6d4ae2bc5daf42Alex Deymo 11253556eccd206bacd5c9c8bb6605bcceb1bcb6190Alex Deymovoid EvaluationContext::ValueChanged(BaseVariable* var) { 113f9f85d6680164064648ce3ed1d31589e1f1b7a29Gilad Arnold DLOG(INFO) << "ValueChanged() called for variable " << var->GetName(); 114f9f85d6680164064648ce3ed1d31589e1f1b7a29Gilad Arnold OnValueChangedOrTimeout(); 11553556eccd206bacd5c9c8bb6605bcceb1bcb6190Alex Deymo} 11653556eccd206bacd5c9c8bb6605bcceb1bcb6190Alex Deymo 117f9f85d6680164064648ce3ed1d31589e1f1b7a29Gilad Arnoldvoid EvaluationContext::OnTimeout() { 118f9f85d6680164064648ce3ed1d31589e1f1b7a29Gilad Arnold DLOG(INFO) << "OnTimeout() called due to " 119f9f85d6680164064648ce3ed1d31589e1f1b7a29Gilad Arnold << (timeout_marks_expiration_ ? "expiration" : "poll interval"); 120509dd5376f47e38d18fe7d29da776e3dc9a9786dAlex Deymo timeout_event_ = MessageLoop::kTaskIdNull; 121f9f85d6680164064648ce3ed1d31589e1f1b7a29Gilad Arnold is_expired_ = timeout_marks_expiration_; 122f9f85d6680164064648ce3ed1d31589e1f1b7a29Gilad Arnold OnValueChangedOrTimeout(); 12353556eccd206bacd5c9c8bb6605bcceb1bcb6190Alex Deymo} 12453556eccd206bacd5c9c8bb6605bcceb1bcb6190Alex Deymo 125f9f85d6680164064648ce3ed1d31589e1f1b7a29Gilad Arnoldvoid EvaluationContext::OnValueChangedOrTimeout() { 126f9f85d6680164064648ce3ed1d31589e1f1b7a29Gilad Arnold // Copy the callback handle locally, allowing it to be reassigned. 12702f7c1dee242f490143791dbb73fa23fa3007cfaBen Chan unique_ptr<Closure> callback = RemoveObserversAndTimeout(); 128f9f85d6680164064648ce3ed1d31589e1f1b7a29Gilad Arnold 129f9f85d6680164064648ce3ed1d31589e1f1b7a29Gilad Arnold if (callback.get()) 130fb794f4b7274576e10b0df291655ad6c88a97df4Gilad Arnold callback->Run(); 13141a75a7ca3f0252f2c9f991dd465aa332e7ce4d1Alex Deymo} 13241a75a7ca3f0252f2c9f991dd465aa332e7ce4d1Alex Deymo 133f329b933db41d26644a97afef928eb1b319d6d99Alex Deymobool EvaluationContext::IsWallclockTimeGreaterThan(Time timestamp) { 134a65fced5f4c2b551616b26ee90a800b44090735fGilad Arnold return IsTimeGreaterThanHelper(timestamp, evaluation_start_wallclock_, 135a65fced5f4c2b551616b26ee90a800b44090735fGilad Arnold &reevaluation_time_wallclock_); 136a65fced5f4c2b551616b26ee90a800b44090735fGilad Arnold} 137a65fced5f4c2b551616b26ee90a800b44090735fGilad Arnold 138f329b933db41d26644a97afef928eb1b319d6d99Alex Deymobool EvaluationContext::IsMonotonicTimeGreaterThan(Time timestamp) { 139a65fced5f4c2b551616b26ee90a800b44090735fGilad Arnold return IsTimeGreaterThanHelper(timestamp, evaluation_start_monotonic_, 140a65fced5f4c2b551616b26ee90a800b44090735fGilad Arnold &reevaluation_time_monotonic_); 14141a75a7ca3f0252f2c9f991dd465aa332e7ce4d1Alex Deymo} 14241a75a7ca3f0252f2c9f991dd465aa332e7ce4d1Alex Deymo 14341a75a7ca3f0252f2c9f991dd465aa332e7ce4d1Alex Deymovoid EvaluationContext::ResetEvaluation() { 144a65fced5f4c2b551616b26ee90a800b44090735fGilad Arnold evaluation_start_wallclock_ = clock_->GetWallclockTime(); 145a65fced5f4c2b551616b26ee90a800b44090735fGilad Arnold evaluation_start_monotonic_ = clock_->GetMonotonicTime(); 146a65fced5f4c2b551616b26ee90a800b44090735fGilad Arnold reevaluation_time_wallclock_ = Time::Max(); 147a65fced5f4c2b551616b26ee90a800b44090735fGilad Arnold reevaluation_time_monotonic_ = Time::Max(); 148f9f85d6680164064648ce3ed1d31589e1f1b7a29Gilad Arnold evaluation_monotonic_deadline_ = MonotonicDeadline(evaluation_timeout_); 14941a75a7ca3f0252f2c9f991dd465aa332e7ce4d1Alex Deymo 15053556eccd206bacd5c9c8bb6605bcceb1bcb6190Alex Deymo // Remove the cached values of non-const variables 15153556eccd206bacd5c9c8bb6605bcceb1bcb6190Alex Deymo for (auto it = value_cache_.begin(); it != value_cache_.end(); ) { 15253556eccd206bacd5c9c8bb6605bcceb1bcb6190Alex Deymo if (it->first->GetMode() == kVariableModeConst) { 15353556eccd206bacd5c9c8bb6605bcceb1bcb6190Alex Deymo ++it; 15453556eccd206bacd5c9c8bb6605bcceb1bcb6190Alex Deymo } else { 15553556eccd206bacd5c9c8bb6605bcceb1bcb6190Alex Deymo it = value_cache_.erase(it); 15653556eccd206bacd5c9c8bb6605bcceb1bcb6190Alex Deymo } 15753556eccd206bacd5c9c8bb6605bcceb1bcb6190Alex Deymo } 15853556eccd206bacd5c9c8bb6605bcceb1bcb6190Alex Deymo} 15953556eccd206bacd5c9c8bb6605bcceb1bcb6190Alex Deymo 160fd45a731d9f9176ce134b34e2a84acc0cf403d1dGilad Arnoldvoid EvaluationContext::ResetExpiration() { 161fd45a731d9f9176ce134b34e2a84acc0cf403d1dGilad Arnold expiration_monotonic_deadline_ = MonotonicDeadline(expiration_timeout_); 162fd45a731d9f9176ce134b34e2a84acc0cf403d1dGilad Arnold is_expired_ = false; 163fd45a731d9f9176ce134b34e2a84acc0cf403d1dGilad Arnold} 164fd45a731d9f9176ce134b34e2a84acc0cf403d1dGilad Arnold 16553556eccd206bacd5c9c8bb6605bcceb1bcb6190Alex Deymobool EvaluationContext::RunOnValueChangeOrTimeout(Closure callback) { 166f9f85d6680164064648ce3ed1d31589e1f1b7a29Gilad Arnold // Check that the method was not called more than once. 16788b591f24cb3f94f982d7024c2e8ed25c2cc26a2Alex Vakulenko if (callback_.get()) { 168f9f85d6680164064648ce3ed1d31589e1f1b7a29Gilad Arnold LOG(ERROR) << "RunOnValueChangeOrTimeout called more than once."; 169f9f85d6680164064648ce3ed1d31589e1f1b7a29Gilad Arnold return false; 17041a75a7ca3f0252f2c9f991dd465aa332e7ce4d1Alex Deymo } 17141a75a7ca3f0252f2c9f991dd465aa332e7ce4d1Alex Deymo 172f9f85d6680164064648ce3ed1d31589e1f1b7a29Gilad Arnold // Check that the context did not yet expire. 173f9f85d6680164064648ce3ed1d31589e1f1b7a29Gilad Arnold if (is_expired()) { 174f9f85d6680164064648ce3ed1d31589e1f1b7a29Gilad Arnold LOG(ERROR) << "RunOnValueChangeOrTimeout called on an expired context."; 17553556eccd206bacd5c9c8bb6605bcceb1bcb6190Alex Deymo return false; 17653556eccd206bacd5c9c8bb6605bcceb1bcb6190Alex Deymo } 17753556eccd206bacd5c9c8bb6605bcceb1bcb6190Alex Deymo 178a65fced5f4c2b551616b26ee90a800b44090735fGilad Arnold // Handle reevaluation due to a Is{Wallclock,Monotonic}TimeGreaterThan(). We 179a65fced5f4c2b551616b26ee90a800b44090735fGilad Arnold // choose the smaller of the differences between evaluation start time and 180a65fced5f4c2b551616b26ee90a800b44090735fGilad Arnold // reevaluation time among the wallclock and monotonic scales. 181a65fced5f4c2b551616b26ee90a800b44090735fGilad Arnold TimeDelta timeout = std::min( 182a65fced5f4c2b551616b26ee90a800b44090735fGilad Arnold GetTimeout(evaluation_start_wallclock_, reevaluation_time_wallclock_), 183a65fced5f4c2b551616b26ee90a800b44090735fGilad Arnold GetTimeout(evaluation_start_monotonic_, reevaluation_time_monotonic_)); 184f9f85d6680164064648ce3ed1d31589e1f1b7a29Gilad Arnold 185f9f85d6680164064648ce3ed1d31589e1f1b7a29Gilad Arnold // Handle reevaluation due to async or poll variables. 186a65fced5f4c2b551616b26ee90a800b44090735fGilad Arnold bool waiting_for_value_change = false; 18753556eccd206bacd5c9c8bb6605bcceb1bcb6190Alex Deymo for (auto& it : value_cache_) { 18853556eccd206bacd5c9c8bb6605bcceb1bcb6190Alex Deymo switch (it.first->GetMode()) { 18953556eccd206bacd5c9c8bb6605bcceb1bcb6190Alex Deymo case kVariableModeAsync: 19053556eccd206bacd5c9c8bb6605bcceb1bcb6190Alex Deymo DLOG(INFO) << "Waiting for value on " << it.first->GetName(); 19153556eccd206bacd5c9c8bb6605bcceb1bcb6190Alex Deymo it.first->AddObserver(this); 192f9f85d6680164064648ce3ed1d31589e1f1b7a29Gilad Arnold waiting_for_value_change = true; 19353556eccd206bacd5c9c8bb6605bcceb1bcb6190Alex Deymo break; 19453556eccd206bacd5c9c8bb6605bcceb1bcb6190Alex Deymo case kVariableModePoll: 195f9f85d6680164064648ce3ed1d31589e1f1b7a29Gilad Arnold timeout = std::min(timeout, it.first->GetPollInterval()); 19653556eccd206bacd5c9c8bb6605bcceb1bcb6190Alex Deymo break; 19753556eccd206bacd5c9c8bb6605bcceb1bcb6190Alex Deymo case kVariableModeConst: 19853556eccd206bacd5c9c8bb6605bcceb1bcb6190Alex Deymo // Ignored. 19953556eccd206bacd5c9c8bb6605bcceb1bcb6190Alex Deymo break; 20053556eccd206bacd5c9c8bb6605bcceb1bcb6190Alex Deymo } 20153556eccd206bacd5c9c8bb6605bcceb1bcb6190Alex Deymo } 202f9f85d6680164064648ce3ed1d31589e1f1b7a29Gilad Arnold 20353556eccd206bacd5c9c8bb6605bcceb1bcb6190Alex Deymo // Check if the re-evaluation is actually being scheduled. If there are no 20453556eccd206bacd5c9c8bb6605bcceb1bcb6190Alex Deymo // events waited for, this function should return false. 205f9f85d6680164064648ce3ed1d31589e1f1b7a29Gilad Arnold if (!waiting_for_value_change && timeout.is_max()) 20653556eccd206bacd5c9c8bb6605bcceb1bcb6190Alex Deymo return false; 207f9f85d6680164064648ce3ed1d31589e1f1b7a29Gilad Arnold 208f9f85d6680164064648ce3ed1d31589e1f1b7a29Gilad Arnold // Ensure that we take into account the expiration timeout. 209f9f85d6680164064648ce3ed1d31589e1f1b7a29Gilad Arnold TimeDelta expiration = RemainingTime(expiration_monotonic_deadline_); 210f9f85d6680164064648ce3ed1d31589e1f1b7a29Gilad Arnold timeout_marks_expiration_ = expiration < timeout; 211f9f85d6680164064648ce3ed1d31589e1f1b7a29Gilad Arnold if (timeout_marks_expiration_) 212f9f85d6680164064648ce3ed1d31589e1f1b7a29Gilad Arnold timeout = expiration; 213f9f85d6680164064648ce3ed1d31589e1f1b7a29Gilad Arnold 214f9f85d6680164064648ce3ed1d31589e1f1b7a29Gilad Arnold // Store the reevaluation callback. 215f9f85d6680164064648ce3ed1d31589e1f1b7a29Gilad Arnold callback_.reset(new Closure(callback)); 216f9f85d6680164064648ce3ed1d31589e1f1b7a29Gilad Arnold 217f9f85d6680164064648ce3ed1d31589e1f1b7a29Gilad Arnold // Schedule a timeout event, if one is set. 218f9f85d6680164064648ce3ed1d31589e1f1b7a29Gilad Arnold if (!timeout.is_max()) { 219f9f85d6680164064648ce3ed1d31589e1f1b7a29Gilad Arnold DLOG(INFO) << "Waiting for timeout in " 220f9f85d6680164064648ce3ed1d31589e1f1b7a29Gilad Arnold << chromeos_update_engine::utils::FormatTimeDelta(timeout); 221509dd5376f47e38d18fe7d29da776e3dc9a9786dAlex Deymo timeout_event_ = MessageLoop::current()->PostDelayedTask( 2220bb234147ea8f0247b733375fcf1685eaf329aacAlex Deymo FROM_HERE, 223f9f85d6680164064648ce3ed1d31589e1f1b7a29Gilad Arnold base::Bind(&EvaluationContext::OnTimeout, 224db799534a8f6ae061ed6d6a46ed800f55d50325bAlex Deymo weak_ptr_factory_.GetWeakPtr()), 225f9f85d6680164064648ce3ed1d31589e1f1b7a29Gilad Arnold timeout); 22653556eccd206bacd5c9c8bb6605bcceb1bcb6190Alex Deymo } 22753556eccd206bacd5c9c8bb6605bcceb1bcb6190Alex Deymo 22853556eccd206bacd5c9c8bb6605bcceb1bcb6190Alex Deymo return true; 22953556eccd206bacd5c9c8bb6605bcceb1bcb6190Alex Deymo} 23053556eccd206bacd5c9c8bb6605bcceb1bcb6190Alex Deymo 231c14902888be0b8d41759e6ff0a7100af4097fd09David Zeuthenstring EvaluationContext::DumpContext() const { 232067053eea5711adb79307f290f05fd0a876be0ebBen Chan auto variables = base::MakeUnique<base::DictionaryValue>(); 233c14902888be0b8d41759e6ff0a7100af4097fd09David Zeuthen for (auto& it : value_cache_) { 234c14902888be0b8d41759e6ff0a7100af4097fd09David Zeuthen variables->SetString(it.first->GetName(), it.second.ToString()); 235c14902888be0b8d41759e6ff0a7100af4097fd09David Zeuthen } 236c14902888be0b8d41759e6ff0a7100af4097fd09David Zeuthen 237c14902888be0b8d41759e6ff0a7100af4097fd09David Zeuthen base::DictionaryValue value; 238067053eea5711adb79307f290f05fd0a876be0ebBen Chan value.Set("variables", std::move(variables)); 239a65fced5f4c2b551616b26ee90a800b44090735fGilad Arnold value.SetString( 240a65fced5f4c2b551616b26ee90a800b44090735fGilad Arnold "evaluation_start_wallclock", 241a65fced5f4c2b551616b26ee90a800b44090735fGilad Arnold chromeos_update_engine::utils::ToString(evaluation_start_wallclock_)); 242a65fced5f4c2b551616b26ee90a800b44090735fGilad Arnold value.SetString( 243a65fced5f4c2b551616b26ee90a800b44090735fGilad Arnold "evaluation_start_monotonic", 244a65fced5f4c2b551616b26ee90a800b44090735fGilad Arnold chromeos_update_engine::utils::ToString(evaluation_start_monotonic_)); 245c14902888be0b8d41759e6ff0a7100af4097fd09David Zeuthen 246c14902888be0b8d41759e6ff0a7100af4097fd09David Zeuthen string json_str; 2476a9d3497bcf57b8b9f5765a2909a51c9f8119cd1Alex Vakulenko base::JSONWriter::WriteWithOptions( 2486a9d3497bcf57b8b9f5765a2909a51c9f8119cd1Alex Vakulenko value, base::JSONWriter::OPTIONS_PRETTY_PRINT, &json_str); 2496e5ab5c011a214aa345ecbba3d910c2ffaec3c83Gilad Arnold base::TrimWhitespaceASCII(json_str, base::TRIM_TRAILING, &json_str); 250c14902888be0b8d41759e6ff0a7100af4097fd09David Zeuthen 251c14902888be0b8d41759e6ff0a7100af4097fd09David Zeuthen return json_str; 252c14902888be0b8d41759e6ff0a7100af4097fd09David Zeuthen} 253c14902888be0b8d41759e6ff0a7100af4097fd09David Zeuthen 25463784a578dd26880454d70797519358a2326291bAlex Deymo} // namespace chromeos_update_manager 255