blob: 5e5305414b44442d7ed1985927314246c39a6d0e [file] [log] [blame]
// Copyright 2019 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.
#import "ios/chrome/browser/ssl/ios_ssl_error_tab_helper.h"
#include "ios/chrome/browser/interstitials/ios_security_interstitial_page.h"
#import "ios/web/public/navigation/navigation_context.h"
#import "ios/web/public/web_state.h"
#import "ios/web/public/web_state/web_state_user_data.h"
#if !defined(__has_feature) || !__has_feature(objc_arc)
#error "This file requires ARC support."
#endif
IOSSSLErrorTabHelper::IOSSSLErrorTabHelper(web::WebState* web_state)
: web_state_(web_state) {
web_state_->AddObserver(this);
}
IOSSSLErrorTabHelper::~IOSSSLErrorTabHelper() = default;
// static
void IOSSSLErrorTabHelper::AssociateBlockingPage(
web::WebState* web_state,
int64_t navigation_id,
std::unique_ptr<IOSSecurityInterstitialPage> blocking_page) {
// CreateForWebState() creates a tab helper if it doesn't exist for
// |web_state| yet.
IOSSSLErrorTabHelper::CreateForWebState(web_state);
IOSSSLErrorTabHelper* helper = IOSSSLErrorTabHelper::FromWebState(web_state);
helper->SetBlockingPage(navigation_id, std::move(blocking_page));
}
// When the navigation finishes and commits the SSL error page, store the
// IOSSecurityInterstitialPage in a member variable so that it can handle
// commands. Clean up the member variable when a subsequent navigation commits,
// since the IOSSecurityInterstitialPage is no longer needed.
void IOSSSLErrorTabHelper::DidFinishNavigation(
web::WebState* web_state,
web::NavigationContext* navigation_context) {
DCHECK_EQ(web_state_, web_state);
if (navigation_context->IsSameDocument()) {
return;
}
auto it = blocking_pages_for_navigations_.find(
navigation_context->GetNavigationId());
if (navigation_context->HasCommitted()) {
if (it == blocking_pages_for_navigations_.end()) {
blocking_page_for_currently_committed_navigation_.reset();
} else {
blocking_page_for_currently_committed_navigation_ = std::move(it->second);
}
}
if (it != blocking_pages_for_navigations_.end()) {
blocking_pages_for_navigations_.erase(it);
}
// Interstitials may change the visibility of the URL or other security state.
web_state_->DidChangeVisibleSecurityState();
}
void IOSSSLErrorTabHelper::WebStateDestroyed(web::WebState* web_state) {
DCHECK_EQ(web_state_, web_state);
web_state_->RemoveObserver(this);
web_state_ = nullptr;
}
void IOSSSLErrorTabHelper::SetBlockingPage(
int64_t navigation_id,
std::unique_ptr<IOSSecurityInterstitialPage> blocking_page) {
blocking_pages_for_navigations_[navigation_id] = std::move(blocking_page);
}
WEB_STATE_USER_DATA_KEY_IMPL(IOSSSLErrorTabHelper)