1// Copyright (c) 2012 The Chromium Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#include "chrome/browser/ui/global_error/global_error_service.h"
6
7#include <algorithm>
8
9#include "base/stl_util.h"
10#include "chrome/browser/chrome_notification_types.h"
11#include "chrome/browser/profiles/profile.h"
12#include "chrome/browser/ui/global_error/global_error.h"
13#include "chrome/browser/ui/global_error/global_error_bubble_view_base.h"
14#include "content/public/browser/notification_service.h"
15
16GlobalErrorService::GlobalErrorService(Profile* profile) : profile_(profile) {
17}
18
19GlobalErrorService::~GlobalErrorService() {
20  STLDeleteElements(&errors_);
21}
22
23void GlobalErrorService::AddGlobalError(GlobalError* error) {
24  DCHECK(error);
25  errors_.push_back(error);
26  NotifyErrorsChanged(error);
27}
28
29void GlobalErrorService::RemoveGlobalError(GlobalError* error) {
30  errors_.erase(std::find(errors_.begin(), errors_.end(), error));
31  GlobalErrorBubbleViewBase* bubble = error->GetBubbleView();
32  if (bubble)
33    bubble->CloseBubbleView();
34  NotifyErrorsChanged(error);
35}
36
37GlobalError* GlobalErrorService::GetGlobalErrorByMenuItemCommandID(
38    int command_id) const {
39  for (GlobalErrorList::const_iterator
40       it = errors_.begin(); it != errors_.end(); ++it) {
41    GlobalError* error = *it;
42    if (error->HasMenuItem() && command_id == error->MenuItemCommandID())
43      return error;
44  }
45  return NULL;
46}
47
48GlobalError*
49GlobalErrorService::GetHighestSeverityGlobalErrorWithWrenchMenuItem() const {
50  GlobalError::Severity highest_severity = GlobalError::SEVERITY_LOW;
51  GlobalError* highest_severity_error = NULL;
52
53  for (GlobalErrorList::const_iterator
54       it = errors_.begin(); it != errors_.end(); ++it) {
55    GlobalError* error = *it;
56    if (error->HasMenuItem()) {
57      if (!highest_severity_error || error->GetSeverity() > highest_severity) {
58        highest_severity = error->GetSeverity();
59        highest_severity_error = error;
60      }
61    }
62  }
63
64  return highest_severity_error;
65}
66
67GlobalError* GlobalErrorService::GetFirstGlobalErrorWithBubbleView() const {
68  for (GlobalErrorList::const_iterator
69       it = errors_.begin(); it != errors_.end(); ++it) {
70    GlobalError* error = *it;
71    if (error->HasBubbleView() && !error->HasShownBubbleView())
72      return error;
73  }
74  return NULL;
75}
76
77void GlobalErrorService::NotifyErrorsChanged(GlobalError* error) {
78  // GlobalErrorService is bound only to original profile so we need to send
79  // notifications to both it and its off-the-record profile to update
80  // incognito windows as well.
81  std::vector<Profile*> profiles_to_notify;
82  if (profile_ != NULL) {
83    profiles_to_notify.push_back(profile_);
84    if (profile_->IsOffTheRecord())
85      profiles_to_notify.push_back(profile_->GetOriginalProfile());
86    else if (profile_->HasOffTheRecordProfile())
87      profiles_to_notify.push_back(profile_->GetOffTheRecordProfile());
88    for (size_t i = 0; i < profiles_to_notify.size(); ++i) {
89      content::NotificationService::current()->Notify(
90        chrome::NOTIFICATION_GLOBAL_ERRORS_CHANGED,
91        content::Source<Profile>(profiles_to_notify[i]),
92        content::Details<GlobalError>(error));
93    }
94  }
95}
96