summaryrefslogtreecommitdiffstats
path: root/chrome/browser/infobars/infobar_service.cc
blob: 3e80ac9317158c55f64447dd3e4d744a686d4af4 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
// Copyright (c) 2013 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/infobars/infobar_service.h"

#include "base/command_line.h"
#include "chrome/browser/chrome_notification_types.h"
#include "chrome/browser/infobars/insecure_content_infobar_delegate.h"
#include "chrome/common/render_messages.h"
#include "components/infobars/core/infobar.h"
#include "content/public/browser/navigation_details.h"
#include "content/public/browser/navigation_entry.h"
#include "content/public/browser/notification_service.h"
#include "content/public/browser/web_contents.h"

DEFINE_WEB_CONTENTS_USER_DATA_KEY(InfoBarService);

using infobars::InfoBar;
using infobars::InfoBarDelegate;
using infobars::InfoBarManager;

namespace {

bool IsReload(const content::LoadCommittedDetails& details) {
  return ui::PageTransitionStripQualifier(
      details.entry->GetTransitionType()) == ui::PAGE_TRANSITION_RELOAD;

}

}  // namespace

// static
InfoBarDelegate::NavigationDetails
    InfoBarService::NavigationDetailsFromLoadCommittedDetails(
        const content::LoadCommittedDetails& details) {
  InfoBarDelegate::NavigationDetails navigation_details;
  navigation_details.entry_id = details.entry->GetUniqueID();
  navigation_details.is_navigation_to_different_page =
      details.is_navigation_to_different_page();
  navigation_details.did_replace_entry = details.did_replace_entry;
  navigation_details.is_main_frame = details.is_main_frame;

  const ui::PageTransition transition = details.entry->GetTransitionType();
  navigation_details.is_reload = IsReload(details);
  navigation_details.is_redirect =
      (transition & ui::PAGE_TRANSITION_IS_REDIRECT_MASK) != 0;

  return navigation_details;
}

// static
content::WebContents* InfoBarService::WebContentsFromInfoBar(InfoBar* infobar) {
  if (!infobar || !infobar->owner())
    return NULL;
  InfoBarService* infobar_service =
      static_cast<InfoBarService*>(infobar->owner());
  return infobar_service->web_contents();
}

InfoBarService::InfoBarService(content::WebContents* web_contents)
    : content::WebContentsObserver(web_contents),
      ignore_next_reload_(false) {
  DCHECK(web_contents);
}

InfoBarService::~InfoBarService() {
  ShutDown();
}

int InfoBarService::GetActiveEntryID() {
  content::NavigationEntry* active_entry =
      web_contents()->GetController().GetActiveEntry();
  return active_entry ? active_entry->GetUniqueID() : 0;
}

void InfoBarService::NotifyInfoBarAdded(InfoBar* infobar) {
  InfoBarManager::NotifyInfoBarAdded(infobar);
  // TODO(droger): Remove the notifications and have listeners change to be
  // InfoBarManager::Observers instead. See http://crbug.com/354380
  content::NotificationService::current()->Notify(
      chrome::NOTIFICATION_TAB_CONTENTS_INFOBAR_ADDED,
      content::Source<InfoBarService>(this),
      content::Details<InfoBar::AddedDetails>(infobar));
}

void InfoBarService::NotifyInfoBarRemoved(InfoBar* infobar, bool animate) {
  InfoBarManager::NotifyInfoBarRemoved(infobar, animate);
  // TODO(droger): Remove the notifications and have listeners change to be
  // InfoBarManager::Observers instead. See http://crbug.com/354380
  InfoBar::RemovedDetails removed_details(infobar, animate);
  content::NotificationService::current()->Notify(
      chrome::NOTIFICATION_TAB_CONTENTS_INFOBAR_REMOVED,
      content::Source<InfoBarService>(this),
      content::Details<InfoBar::RemovedDetails>(&removed_details));
}

// InfoBarService::CreateConfirmInfoBar() is implemented in platform-specific
// files.

void InfoBarService::RenderProcessGone(base::TerminationStatus status) {
  RemoveAllInfoBars(true);
}

void InfoBarService::DidStartNavigationToPendingEntry(
    const GURL& url,
    content::NavigationController::ReloadType reload_type) {
  ignore_next_reload_ = false;
}

void InfoBarService::NavigationEntryCommitted(
    const content::LoadCommittedDetails& load_details) {
  const bool ignore = ignore_next_reload_ && IsReload(load_details);
  ignore_next_reload_ = false;
  if (!ignore)
    OnNavigation(NavigationDetailsFromLoadCommittedDetails(load_details));
}

void InfoBarService::WebContentsDestroyed() {
  // The WebContents is going away; be aggressively paranoid and delete
  // ourselves lest other parts of the system attempt to add infobars or use
  // us otherwise during the destruction.
  web_contents()->RemoveUserData(UserDataKey());
  // That was the equivalent of "delete this". This object is now destroyed;
  // returning from this function is the only safe thing to do.
}

bool InfoBarService::OnMessageReceived(const IPC::Message& message) {
  bool handled = true;
  IPC_BEGIN_MESSAGE_MAP(InfoBarService, message)
    IPC_MESSAGE_HANDLER(ChromeViewHostMsg_DidBlockDisplayingInsecureContent,
                        OnDidBlockDisplayingInsecureContent)
    IPC_MESSAGE_HANDLER(ChromeViewHostMsg_DidBlockRunningInsecureContent,
                        OnDidBlockRunningInsecureContent)
    IPC_MESSAGE_UNHANDLED(handled = false)
  IPC_END_MESSAGE_MAP()
  return handled;
}

void InfoBarService::OnDidBlockDisplayingInsecureContent() {
  InsecureContentInfoBarDelegate::Create(
      this, InsecureContentInfoBarDelegate::DISPLAY);
}

void InfoBarService::OnDidBlockRunningInsecureContent() {
  InsecureContentInfoBarDelegate::Create(this,
                                         InsecureContentInfoBarDelegate::RUN);
}