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);
}
|