Index: chrome/browser/media/router/issue_manager.cc |
diff --git a/chrome/browser/media/router/issue_manager.cc b/chrome/browser/media/router/issue_manager.cc |
new file mode 100644 |
index 0000000000000000000000000000000000000000..effacbca3d5988032ff9ef10a47e2954b027e761 |
--- /dev/null |
+++ b/chrome/browser/media/router/issue_manager.cc |
@@ -0,0 +1,113 @@ |
+// Copyright 2015 The Chromium Authors. All rights reserved. |
+// Use of this source code is governed by a BSD-style license that can be |
+// found in the LICENSE file. |
+ |
+#include "chrome/browser/media/router/issue_manager.h" |
+ |
+namespace media_router { |
+ |
+IssueManager::IssueManager() : top_issue_(nullptr) { |
+} |
+ |
+IssueManager::~IssueManager() { |
+} |
+ |
+void IssueManager::AddIssue(const Issue& issue) { |
+ DCHECK(thread_checker_.CalledOnValidThread()); |
+ media_issue_map_.insert(std::make_pair(issue.id(), issue)); |
+ |
+ MaybeUpdateTopIssue(); |
+} |
+ |
+void IssueManager::ClearIssue(const IssueId& issue_id) { |
+ DCHECK(thread_checker_.CalledOnValidThread()); |
+ media_issue_map_.erase(issue_id); |
+ |
+ MaybeUpdateTopIssue(); |
+} |
+ |
+size_t IssueManager::GetIssueCount() const { |
+ DCHECK(thread_checker_.CalledOnValidThread()); |
+ return media_issue_map_.size(); |
+} |
+ |
+void IssueManager::ClearAllIssues() { |
+ DCHECK(thread_checker_.CalledOnValidThread()); |
+ media_issue_map_.clear(); |
+ |
+ MaybeUpdateTopIssue(); |
+} |
+ |
+void IssueManager::ClearGlobalIssues() { |
+ DCHECK(thread_checker_.CalledOnValidThread()); |
+ auto it = media_issue_map_.begin(); |
+ while (it != media_issue_map_.end()) { |
+ if (it->second.IsGlobal()) { |
+ media_issue_map_.erase(it++); |
+ } else { |
+ ++it; |
+ } |
+ } |
+ |
+ MaybeUpdateTopIssue(); |
+} |
+ |
+void IssueManager::ClearIssuesWithRouteId(const MediaRouteId& route_id) { |
+ DCHECK(thread_checker_.CalledOnValidThread()); |
+ auto it = media_issue_map_.begin(); |
+ while (it != media_issue_map_.end()) { |
+ if (it->second.route_id() == route_id) { |
+ media_issue_map_.erase(it++); |
+ } else { |
+ ++it; |
+ } |
+ } |
+ |
+ MaybeUpdateTopIssue(); |
+} |
+ |
+void IssueManager::RegisterObserver(IssuesObserver* observer) { |
+ DCHECK(thread_checker_.CalledOnValidThread()); |
+ DCHECK(observer); |
+ DCHECK(!issues_observers_.HasObserver(observer)); |
+ |
+ issues_observers_.AddObserver(observer); |
+ if (top_issue_) |
+ observer->OnIssueUpdated(top_issue_); |
+} |
+ |
+void IssueManager::UnregisterObserver(IssuesObserver* observer) { |
+ DCHECK(thread_checker_.CalledOnValidThread()); |
+ issues_observers_.RemoveObserver(observer); |
+} |
+ |
+void IssueManager::MaybeUpdateTopIssue() { |
+ Issue* new_top_issue = nullptr; |
+ if (!media_issue_map_.empty()) { |
+ auto it = media_issue_map_.begin(); |
+ |
+ // Assumes there's at least one issue in the map. This is the first issue |
+ // regardless of whether it's blocking or not. |
+ new_top_issue = &it->second; |
+ |
+ while (it != media_issue_map_.end()) { |
DaleCurtis
2015/04/30 18:18:15
Seems like you might want some form of a priority
Kevin M
2015/05/01 17:59:18
Hmmm. There are multiple different access patterns
apacible
2015/05/01 20:18:08
std::list looks fine to me.
|
+ // The first blocking issue is of higher priority than the first issue. |
+ if (it->second.IsBlocking()) { |
+ new_top_issue = &it->second; |
+ break; |
+ } |
+ |
+ ++it; |
+ } |
+ } |
+ |
+ // If the top issue is different from |top_issue_|, update. |
+ if (new_top_issue != top_issue_) { |
+ top_issue_ = new_top_issue; |
+ |
+ FOR_EACH_OBSERVER(IssuesObserver, issues_observers_, |
+ OnIssueUpdated(top_issue_)); |
+ } |
+} |
+ |
+} // namespace media_router |