| OLD | NEW |
| 1 // Copyright 2014 The Chromium Authors. All rights reserved. | 1 // Copyright 2014 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "components/update_client/update_client.h" | 5 #include "components/update_client/update_client.h" |
| 6 | 6 |
| 7 #include <algorithm> | 7 #include <algorithm> |
| 8 #include <queue> | 8 #include <queue> |
| 9 #include <set> | 9 #include <set> |
| 10 #include <utility> | 10 #include <utility> |
| (...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 82 UpdateClientImpl::~UpdateClientImpl() { | 82 UpdateClientImpl::~UpdateClientImpl() { |
| 83 DCHECK(thread_checker_.CalledOnValidThread()); | 83 DCHECK(thread_checker_.CalledOnValidThread()); |
| 84 config_ = nullptr; | 84 config_ = nullptr; |
| 85 } | 85 } |
| 86 | 86 |
| 87 void UpdateClientImpl::Install(const std::string& id, | 87 void UpdateClientImpl::Install(const std::string& id, |
| 88 const CrxDataCallback& crx_data_callback, | 88 const CrxDataCallback& crx_data_callback, |
| 89 const CompletionCallback& completion_callback) { | 89 const CompletionCallback& completion_callback) { |
| 90 DCHECK(thread_checker_.CalledOnValidThread()); | 90 DCHECK(thread_checker_.CalledOnValidThread()); |
| 91 | 91 |
| 92 if (update_engine_->IsUpdating(id)) { | 92 if (IsUpdating(id)) { |
| 93 completion_callback.Run(Error::ERROR_UPDATE_IN_PROGRESS); | 93 completion_callback.Run(Error::ERROR_UPDATE_IN_PROGRESS); |
| 94 return; | 94 return; |
| 95 } | 95 } |
| 96 | 96 |
| 97 std::vector<std::string> ids; | 97 std::vector<std::string> ids; |
| 98 ids.push_back(id); | 98 ids.push_back(id); |
| 99 | 99 |
| 100 // Partially applies |completion_callback| to OnTaskComplete, so this | 100 // Partially applies |completion_callback| to OnTaskComplete, so this |
| 101 // argument is available when the task completes, along with the task itself. | 101 // argument is available when the task completes, along with the task itself. |
| 102 const auto callback = | 102 const auto callback = |
| 103 base::Bind(&UpdateClientImpl::OnTaskComplete, this, completion_callback); | 103 base::Bind(&UpdateClientImpl::OnTaskComplete, this, completion_callback); |
| 104 scoped_ptr<TaskUpdate> task(new TaskUpdate(update_engine_.get(), true, ids, | 104 scoped_ptr<TaskUpdate> task(new TaskUpdate(update_engine_.get(), true, ids, |
| 105 crx_data_callback, callback)); | 105 crx_data_callback, callback)); |
| 106 | 106 |
| 107 // Install tasks are run concurrently and never queued up. |
| 107 auto it = tasks_.insert(task.release()).first; | 108 auto it = tasks_.insert(task.release()).first; |
| 108 RunTask(*it); | 109 RunTask(*it); |
| 109 } | 110 } |
| 110 | 111 |
| 111 void UpdateClientImpl::Update(const std::vector<std::string>& ids, | 112 void UpdateClientImpl::Update(const std::vector<std::string>& ids, |
| 112 const CrxDataCallback& crx_data_callback, | 113 const CrxDataCallback& crx_data_callback, |
| 113 const CompletionCallback& completion_callback) { | 114 const CompletionCallback& completion_callback) { |
| 114 DCHECK(thread_checker_.CalledOnValidThread()); | 115 DCHECK(thread_checker_.CalledOnValidThread()); |
| 115 | 116 |
| 116 const auto callback = | 117 const auto callback = |
| 117 base::Bind(&UpdateClientImpl::OnTaskComplete, this, completion_callback); | 118 base::Bind(&UpdateClientImpl::OnTaskComplete, this, completion_callback); |
| 118 scoped_ptr<TaskUpdate> task(new TaskUpdate(update_engine_.get(), false, ids, | 119 scoped_ptr<TaskUpdate> task(new TaskUpdate(update_engine_.get(), false, ids, |
| 119 crx_data_callback, callback)); | 120 crx_data_callback, callback)); |
| 120 | 121 |
| 122 // If no other tasks are running at the moment, run this update task. |
| 123 // Otherwise, queue the task up. |
| 121 if (tasks_.empty()) { | 124 if (tasks_.empty()) { |
| 122 auto it = tasks_.insert(task.release()).first; | 125 auto it = tasks_.insert(task.release()).first; |
| 123 RunTask(*it); | 126 RunTask(*it); |
| 124 } else { | 127 } else { |
| 125 task_queue_.push(task.release()); | 128 task_queue_.push(task.release()); |
| 126 } | 129 } |
| 127 } | 130 } |
| 128 | 131 |
| 129 void UpdateClientImpl::RunTask(Task* task) { | 132 void UpdateClientImpl::RunTask(Task* task) { |
| 130 DCHECK(thread_checker_.CalledOnValidThread()); | 133 DCHECK(thread_checker_.CalledOnValidThread()); |
| 131 base::ThreadTaskRunnerHandle::Get()->PostTask( | 134 base::ThreadTaskRunnerHandle::Get()->PostTask( |
| 132 FROM_HERE, base::Bind(&Task::Run, base::Unretained(task))); | 135 FROM_HERE, base::Bind(&Task::Run, base::Unretained(task))); |
| 133 } | 136 } |
| 134 | 137 |
| 135 void UpdateClientImpl::OnTaskComplete( | 138 void UpdateClientImpl::OnTaskComplete( |
| 136 const CompletionCallback& completion_callback, | 139 const CompletionCallback& completion_callback, |
| 137 Task* task, | 140 Task* task, |
| 138 int error) { | 141 int error) { |
| 139 DCHECK(thread_checker_.CalledOnValidThread()); | 142 DCHECK(thread_checker_.CalledOnValidThread()); |
| 140 DCHECK(task); | 143 DCHECK(task); |
| 141 | 144 |
| 142 base::ThreadTaskRunnerHandle::Get()->PostTask( | 145 base::ThreadTaskRunnerHandle::Get()->PostTask( |
| 143 FROM_HERE, base::Bind(completion_callback, error)); | 146 FROM_HERE, base::Bind(completion_callback, error)); |
| 144 | 147 |
| 145 tasks_.erase(task); | 148 tasks_.erase(task); |
| 146 delete task; | 149 delete task; |
| 147 | 150 |
| 148 if (!task_queue_.empty()) { | 151 // Pick up a task from the queue if the queue has pending tasks and no other |
| 152 // task is running. |
| 153 if (tasks_.empty() && !task_queue_.empty()) { |
| 149 RunTask(task_queue_.front()); | 154 RunTask(task_queue_.front()); |
| 150 task_queue_.pop(); | 155 task_queue_.pop(); |
| 151 } | 156 } |
| 152 } | 157 } |
| 153 | 158 |
| 154 void UpdateClientImpl::AddObserver(Observer* observer) { | 159 void UpdateClientImpl::AddObserver(Observer* observer) { |
| 155 DCHECK(thread_checker_.CalledOnValidThread()); | 160 DCHECK(thread_checker_.CalledOnValidThread()); |
| 156 observer_list_.AddObserver(observer); | 161 observer_list_.AddObserver(observer); |
| 157 } | 162 } |
| 158 | 163 |
| 159 void UpdateClientImpl::RemoveObserver(Observer* observer) { | 164 void UpdateClientImpl::RemoveObserver(Observer* observer) { |
| 160 DCHECK(thread_checker_.CalledOnValidThread()); | 165 DCHECK(thread_checker_.CalledOnValidThread()); |
| 161 observer_list_.RemoveObserver(observer); | 166 observer_list_.RemoveObserver(observer); |
| 162 } | 167 } |
| 163 | 168 |
| 164 void UpdateClientImpl::NotifyObservers(Observer::Events event, | 169 void UpdateClientImpl::NotifyObservers(Observer::Events event, |
| 165 const std::string& id) { | 170 const std::string& id) { |
| 166 DCHECK(thread_checker_.CalledOnValidThread()); | 171 DCHECK(thread_checker_.CalledOnValidThread()); |
| 167 FOR_EACH_OBSERVER(Observer, observer_list_, OnEvent(event, id)); | 172 FOR_EACH_OBSERVER(Observer, observer_list_, OnEvent(event, id)); |
| 168 } | 173 } |
| 169 | 174 |
| 170 bool UpdateClientImpl::GetCrxUpdateState(const std::string& id, | 175 bool UpdateClientImpl::GetCrxUpdateState(const std::string& id, |
| 171 CrxUpdateItem* update_item) const { | 176 CrxUpdateItem* update_item) const { |
| 172 return update_engine_->GetUpdateState(id, update_item); | 177 return update_engine_->GetUpdateState(id, update_item); |
| 173 } | 178 } |
| 174 | 179 |
| 175 bool UpdateClientImpl::IsUpdating(const std::string& id) const { | 180 bool UpdateClientImpl::IsUpdating(const std::string& id) const { |
| 176 return update_engine_->IsUpdating(id); | 181 DCHECK(thread_checker_.CalledOnValidThread()); |
| 182 |
| 183 for (const auto& task : tasks_) { |
| 184 const auto ids(task->GetIds()); |
| 185 if (std::find(std::begin(ids), std::end(ids), id) != std::end(ids)) { |
| 186 return true; |
| 187 } |
| 188 } |
| 189 |
| 190 return false; |
| 177 } | 191 } |
| 178 | 192 |
| 179 scoped_refptr<UpdateClient> UpdateClientFactory( | 193 scoped_refptr<UpdateClient> UpdateClientFactory( |
| 180 const scoped_refptr<Configurator>& config) { | 194 const scoped_refptr<Configurator>& config) { |
| 181 scoped_ptr<PingManager> ping_manager(new PingManager(*config)); | 195 scoped_ptr<PingManager> ping_manager(new PingManager(*config)); |
| 182 return new UpdateClientImpl(config, ping_manager.Pass(), | 196 return new UpdateClientImpl(config, ping_manager.Pass(), |
| 183 &UpdateChecker::Create, &CrxDownloader::Create); | 197 &UpdateChecker::Create, &CrxDownloader::Create); |
| 184 } | 198 } |
| 185 | 199 |
| 186 } // namespace update_client | 200 } // namespace update_client |
| OLD | NEW |