Commit a8bd4724 authored by Chris Lu's avatar Chris Lu Committed by Commit Bot

[ios] Refactor implementations of InfobarBannerInteractionHandler

Move common implementations of InfobarBannerInteractionHandler by its
subclasses into InfobarBannerInteractionHandler.

The DCHECK(inserter_) in OverlayTabHelper is removed, because it can
easily lead to tests failing if the ordering of creating TabHelper
will fail here.

Bug: 1071914
Change-Id: I1f4c8a212aac29112810a2a8b4fef33da909fa84
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2219039
Commit-Queue: Chris Lu <thegreenfrog@chromium.org>
Reviewed-by: default avatarKurt Horimoto <kkhorimoto@chromium.org>
Cr-Commit-Position: refs/heads/master@{#774228}
parent a036fbde
...@@ -16,6 +16,8 @@ source_set("common") { ...@@ -16,6 +16,8 @@ source_set("common") {
] ]
deps = [ deps = [
"//base", "//base",
"//ios/chrome/browser/infobars",
"//ios/chrome/browser/infobars/overlays",
"//ios/chrome/browser/infobars/overlays:util", "//ios/chrome/browser/infobars/overlays:util",
"//ios/chrome/browser/infobars/overlays/browser_agent/interaction_handlers", "//ios/chrome/browser/infobars/overlays/browser_agent/interaction_handlers",
"//ios/chrome/browser/overlays", "//ios/chrome/browser/overlays",
...@@ -29,6 +31,7 @@ source_set("unit_tests") { ...@@ -29,6 +31,7 @@ source_set("unit_tests") {
configs += [ "//build/config/compiler:enable_arc" ] configs += [ "//build/config/compiler:enable_arc" ]
testonly = true testonly = true
sources = [ sources = [
"infobar_banner_interaction_handler_unittest.mm",
"infobar_banner_overlay_request_callback_installer_unittest.mm", "infobar_banner_overlay_request_callback_installer_unittest.mm",
"infobar_modal_overlay_request_callback_installer_unittest.mm", "infobar_modal_overlay_request_callback_installer_unittest.mm",
] ]
...@@ -38,6 +41,8 @@ source_set("unit_tests") { ...@@ -38,6 +41,8 @@ source_set("unit_tests") {
"//ios/chrome/browser/browser_state:test_support", "//ios/chrome/browser/browser_state:test_support",
"//ios/chrome/browser/infobars", "//ios/chrome/browser/infobars",
"//ios/chrome/browser/infobars:public", "//ios/chrome/browser/infobars:public",
"//ios/chrome/browser/infobars/overlays",
"//ios/chrome/browser/infobars/overlays:util",
"//ios/chrome/browser/infobars/overlays/browser_agent/interaction_handlers/common/test", "//ios/chrome/browser/infobars/overlays/browser_agent/interaction_handlers/common/test",
"//ios/chrome/browser/infobars/overlays/browser_agent/interaction_handlers/test", "//ios/chrome/browser/infobars/overlays/browser_agent/interaction_handlers/test",
"//ios/chrome/browser/infobars/test", "//ios/chrome/browser/infobars/test",
...@@ -48,6 +53,8 @@ source_set("unit_tests") { ...@@ -48,6 +53,8 @@ source_set("unit_tests") {
"//ios/chrome/browser/overlays/public/infobar_banner", "//ios/chrome/browser/overlays/public/infobar_banner",
"//ios/chrome/browser/overlays/public/infobar_modal", "//ios/chrome/browser/overlays/public/infobar_modal",
"//ios/chrome/browser/overlays/test", "//ios/chrome/browser/overlays/test",
"//ios/chrome/browser/passwords/test",
"//ios/chrome/browser/ui/infobars:feature_flags",
"//ios/chrome/browser/web_state_list", "//ios/chrome/browser/web_state_list",
"//ios/chrome/browser/web_state_list:test_support", "//ios/chrome/browser/web_state_list:test_support",
"//ios/chrome/test:test_support", "//ios/chrome/test:test_support",
......
...@@ -13,31 +13,31 @@ namespace web { ...@@ -13,31 +13,31 @@ namespace web {
class WebState; class WebState;
} }
// A InfobarInteractionHandler::InteractionHandler, intended to be subclassed, // A InfobarInteractionHandler::InteractionHandler, that handles interaction
// that handles interaction events for an infobar banner. // events for the high-level confirm infobar banner. This class can be
// subclassed to handle events differently for a different Infobar.
class InfobarBannerInteractionHandler class InfobarBannerInteractionHandler
: public InfobarInteractionHandler::Handler { : public InfobarInteractionHandler::Handler {
public: public:
// Constructor for a banner interaction handler that creates callback
// installers with |request_support|.
explicit InfobarBannerInteractionHandler(
const OverlayRequestSupport* request_support);
~InfobarBannerInteractionHandler() override; ~InfobarBannerInteractionHandler() override;
// Updates the model when the visibility of |infobar|'s banner is changed. // Updates the model when the visibility of |infobar|'s banner is changed.
virtual void BannerVisibilityChanged(InfoBarIOS* infobar, bool visible) = 0; virtual void BannerVisibilityChanged(InfoBarIOS* infobar, bool visible);
// Updates the model when the main button is tapped for |infobar|'s banner. // Updates the model when the main button is tapped for |infobar|'s banner.
virtual void MainButtonTapped(InfoBarIOS* infobar) = 0; virtual void MainButtonTapped(InfoBarIOS* infobar) {}
// Shows the modal when the modal button is tapped for |infobar|'s banner. // Shows the modal when the modal button is tapped for |infobar|'s banner.
// |web_state| is the WebState associated with |infobar|'s InfoBarManager. // |web_state| is the WebState associated with |infobar|'s InfoBarManager.
virtual void ShowModalButtonTapped(InfoBarIOS* infobar, virtual void ShowModalButtonTapped(InfoBarIOS* infobar,
web::WebState* web_state) = 0; web::WebState* web_state);
// Notifies the model that the upcoming dismissal is user-initiated (i.e. // Notifies the model that the upcoming dismissal is user-initiated (i.e.
// swipe dismissal in the refresh UI). // swipe dismissal in the refresh UI).
virtual void BannerDismissedByUser(InfoBarIOS* infobar) = 0; virtual void BannerDismissedByUser(InfoBarIOS* infobar);
protected: protected:
// Constructor for a banner interaction handler that creates callback
// installers with |request_support|.
explicit InfobarBannerInteractionHandler(
const OverlayRequestSupport* request_support);
// InfobarInteractionHandler::Handler: // InfobarInteractionHandler::Handler:
std::unique_ptr<OverlayRequestCallbackInstaller> CreateInstaller() override; std::unique_ptr<OverlayRequestCallbackInstaller> CreateInstaller() override;
void InfobarVisibilityChanged(InfoBarIOS* infobar, bool visible) override; void InfobarVisibilityChanged(InfoBarIOS* infobar, bool visible) override;
......
...@@ -5,12 +5,26 @@ ...@@ -5,12 +5,26 @@
#import "ios/chrome/browser/infobars/overlays/browser_agent/interaction_handlers/common/infobar_banner_interaction_handler.h" #import "ios/chrome/browser/infobars/overlays/browser_agent/interaction_handlers/common/infobar_banner_interaction_handler.h"
#include "base/check.h" #include "base/check.h"
#include "base/logging.h"
#include "components/infobars/core/confirm_infobar_delegate.h"
#include "ios/chrome/browser/infobars/infobar_ios.h"
#import "ios/chrome/browser/infobars/overlays/browser_agent/interaction_handlers/common/infobar_banner_overlay_request_callback_installer.h" #import "ios/chrome/browser/infobars/overlays/browser_agent/interaction_handlers/common/infobar_banner_overlay_request_callback_installer.h"
#import "ios/chrome/browser/infobars/overlays/infobar_overlay_request_inserter.h"
#import "ios/chrome/browser/overlays/public/overlay_request_queue.h"
#if !defined(__has_feature) || !__has_feature(objc_arc) #if !defined(__has_feature) || !__has_feature(objc_arc)
#error "This file requires ARC support." #error "This file requires ARC support."
#endif #endif
namespace {
ConfirmInfoBarDelegate* GetInfobarDelegate(InfoBarIOS* infobar) {
ConfirmInfoBarDelegate* delegate =
infobar->delegate()->AsConfirmInfoBarDelegate();
DCHECK(delegate);
return delegate;
}
} // namespace
InfobarBannerInteractionHandler::InfobarBannerInteractionHandler( InfobarBannerInteractionHandler::InfobarBannerInteractionHandler(
const OverlayRequestSupport* request_support) const OverlayRequestSupport* request_support)
: request_support_(request_support) { : request_support_(request_support) {
...@@ -25,6 +39,38 @@ InfobarBannerInteractionHandler::CreateInstaller() { ...@@ -25,6 +39,38 @@ InfobarBannerInteractionHandler::CreateInstaller() {
request_support_, this); request_support_, this);
} }
void InfobarBannerInteractionHandler::BannerVisibilityChanged(
InfoBarIOS* infobar,
bool visible) {
if (!visible)
GetInfobarDelegate(infobar)->InfoBarDismissed();
}
void InfobarBannerInteractionHandler::ShowModalButtonTapped(
InfoBarIOS* infobar,
web::WebState* web_state) {
InsertParams params(infobar);
params.infobar = infobar;
params.overlay_type = InfobarOverlayType::kModal;
params.insertion_index = OverlayRequestQueue::FromWebState(
web_state, OverlayModality::kInfobarModal)
->size();
params.source = InfobarOverlayInsertionSource::kBanner;
InfobarOverlayRequestInserter::FromWebState(web_state)->InsertOverlayRequest(
params);
}
void InfobarBannerInteractionHandler::BannerDismissedByUser(
InfoBarIOS* infobar) {
// Notify the delegate that a user-initiated dismissal has been triggered.
// NOTE: InfoBarDismissed() (camel cased) is used to notify the delegate that
// the user initiated the upcoming dismissal (i.e. swiped to dismiss in the
// refresh UI). InfobarDismissed() (not camel cased) is called in
// BannerVisibilityChanged() to notify the delegate of the dismissal of the
// UI.
GetInfobarDelegate(infobar)->InfoBarDismissed();
}
void InfobarBannerInteractionHandler::InfobarVisibilityChanged( void InfobarBannerInteractionHandler::InfobarVisibilityChanged(
InfoBarIOS* infobar, InfoBarIOS* infobar,
bool visible) { bool visible) {
......
// Copyright 2020 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/infobars/overlays/browser_agent/interaction_handlers/common/infobar_banner_interaction_handler.h"
#include "base/test/scoped_feature_list.h"
#include "components/infobars/core/infobar_feature.h"
#include "ios/chrome/browser/infobars/infobar_manager_impl.h"
#import "ios/chrome/browser/infobars/overlays/infobar_overlay_request_inserter.h"
#include "ios/chrome/browser/infobars/overlays/infobar_overlay_util.h"
#import "ios/chrome/browser/infobars/test/fake_infobar_ios.h"
#import "ios/chrome/browser/overlays/public/infobar_banner/save_password_infobar_banner_overlay.h"
#import "ios/chrome/browser/overlays/public/overlay_request_queue.h"
#import "ios/chrome/browser/passwords/test/mock_ios_chrome_save_passwords_infobar_delegate.h"
#import "ios/chrome/browser/ui/infobars/infobar_feature.h"
#import "ios/web/public/test/fakes/test_navigation_manager.h"
#import "ios/web/public/test/fakes/test_web_state.h"
#include "testing/platform_test.h"
#if !defined(__has_feature) || !__has_feature(objc_arc)
#error "This file requires ARC support."
#endif
// Test fixture for InfobarBannerInteractionHandler.
class InfobarBannerInteractionHandlerTest : public PlatformTest {
public:
InfobarBannerInteractionHandlerTest()
: handler_(
SavePasswordInfobarBannerOverlayRequestConfig::RequestSupport()) {
scoped_feature_list_.InitWithFeatures({kIOSInfobarUIReboot},
{kInfobarUIRebootOnlyiOS13});
web_state_.SetNavigationManager(
std::make_unique<web::TestNavigationManager>());
InfoBarManagerImpl::CreateForWebState(&web_state_);
InfobarOverlayRequestInserter::CreateForWebState(&web_state_);
std::unique_ptr<InfoBarIOS> infobar = std::make_unique<InfoBarIOS>(
InfobarType::kInfobarTypePasswordSave,
MockIOSChromeSavePasswordInfoBarDelegate::Create(@"username",
@"password"));
infobar_ = infobar.get();
InfoBarManagerImpl::FromWebState(&web_state_)
->AddInfoBar(std::move(infobar));
}
MockIOSChromeSavePasswordInfoBarDelegate& mock_delegate() {
return *static_cast<MockIOSChromeSavePasswordInfoBarDelegate*>(
infobar_->delegate());
}
protected:
base::test::ScopedFeatureList scoped_feature_list_;
InfobarBannerInteractionHandler handler_;
web::TestWebState web_state_;
InfoBarIOS* infobar_;
};
// Tests that BannerVisibilityChanged() calls InfobarPresenting() and
// InfobarDismissed() on the mock delegate.
TEST_F(InfobarBannerInteractionHandlerTest, Presentation) {
EXPECT_CALL(mock_delegate(), InfoBarDismissed());
handler_.BannerVisibilityChanged(infobar_, false);
}
// Tests that pressing the modal button calls adds an OverlayRequest for the
// modal UI to the WebState's queue at OverlayModality::kInfobarModal.
TEST_F(InfobarBannerInteractionHandlerTest, ShowModal) {
OverlayRequestQueue* queue = OverlayRequestQueue::FromWebState(
&web_state_, OverlayModality::kInfobarModal);
ASSERT_EQ(0U, queue->size());
handler_.ShowModalButtonTapped(infobar_, &web_state_);
OverlayRequest* modal_request = queue->front_request();
EXPECT_TRUE(modal_request);
EXPECT_EQ(infobar_, GetOverlayRequestInfobar(modal_request));
}
// Tests that BannerVisibilityChanged() calls InfobarDismissed() on the mock
// delegate.
TEST_F(InfobarBannerInteractionHandlerTest, UserInitiatedDismissal) {
EXPECT_CALL(mock_delegate(), InfoBarDismissed());
handler_.BannerDismissedByUser(infobar_);
}
...@@ -18,11 +18,7 @@ class ConfirmInfobarBannerInteractionHandler ...@@ -18,11 +18,7 @@ class ConfirmInfobarBannerInteractionHandler
~ConfirmInfobarBannerInteractionHandler() override; ~ConfirmInfobarBannerInteractionHandler() override;
// InfobarBannerInteractionHandler: // InfobarBannerInteractionHandler:
void BannerVisibilityChanged(InfoBarIOS* infobar, bool visible) override;
void MainButtonTapped(InfoBarIOS* infobar) override; void MainButtonTapped(InfoBarIOS* infobar) override;
void ShowModalButtonTapped(InfoBarIOS* infobar,
web::WebState* web_state) override;
void BannerDismissedByUser(InfoBarIOS* infobar) override;
private: private:
// Returns the password delegate from |infobar|. // Returns the password delegate from |infobar|.
......
...@@ -24,36 +24,11 @@ ConfirmInfobarBannerInteractionHandler::ConfirmInfobarBannerInteractionHandler() ...@@ -24,36 +24,11 @@ ConfirmInfobarBannerInteractionHandler::ConfirmInfobarBannerInteractionHandler()
ConfirmInfobarBannerInteractionHandler:: ConfirmInfobarBannerInteractionHandler::
~ConfirmInfobarBannerInteractionHandler() = default; ~ConfirmInfobarBannerInteractionHandler() = default;
void ConfirmInfobarBannerInteractionHandler::BannerVisibilityChanged(
InfoBarIOS* infobar,
bool visible) {
if (!visible) {
GetInfobarDelegate(infobar)->InfoBarDismissed();
}
}
void ConfirmInfobarBannerInteractionHandler::MainButtonTapped( void ConfirmInfobarBannerInteractionHandler::MainButtonTapped(
InfoBarIOS* infobar) { InfoBarIOS* infobar) {
infobar->set_accepted(GetInfobarDelegate(infobar)->Accept()); infobar->set_accepted(GetInfobarDelegate(infobar)->Accept());
} }
void ConfirmInfobarBannerInteractionHandler::ShowModalButtonTapped(
InfoBarIOS* infobar,
web::WebState* web_state) {
NOTREACHED();
}
void ConfirmInfobarBannerInteractionHandler::BannerDismissedByUser(
InfoBarIOS* infobar) {
// Notify the delegate that a user-initiated dismissal has been triggered.
// NOTE: InfoBarDismissed() (camel cased) is used to notify the delegate that
// the user initiated the upcoming dismissal (i.e. swiped to dismiss in the
// refresh UI). InfobarDismissed() (not camel cased) is called in
// BannerVisibilityChanged() to notify the delegate of the dismissal of the
// UI.
GetInfobarDelegate(infobar)->InfoBarDismissed();
}
#pragma mark - Private #pragma mark - Private
ConfirmInfoBarDelegate* ConfirmInfoBarDelegate*
......
...@@ -52,13 +52,6 @@ class ConfirmInfobarBannerInteractionHandlerTest : public PlatformTest { ...@@ -52,13 +52,6 @@ class ConfirmInfobarBannerInteractionHandlerTest : public PlatformTest {
InfoBarIOS* infobar_; InfoBarIOS* infobar_;
}; };
// Tests that BannerVisibilityChanged() calls InfobarDismissed() on the mock
// delegate.
TEST_F(ConfirmInfobarBannerInteractionHandlerTest, Presentation) {
EXPECT_CALL(mock_delegate(), InfoBarDismissed());
handler_.BannerVisibilityChanged(infobar_, false);
}
// Tests MainButtonTapped() calls Accept() on the mock delegate and resets // Tests MainButtonTapped() calls Accept() on the mock delegate and resets
// the infobar to be accepted. // the infobar to be accepted.
TEST_F(ConfirmInfobarBannerInteractionHandlerTest, MainButton) { TEST_F(ConfirmInfobarBannerInteractionHandlerTest, MainButton) {
...@@ -67,10 +60,3 @@ TEST_F(ConfirmInfobarBannerInteractionHandlerTest, MainButton) { ...@@ -67,10 +60,3 @@ TEST_F(ConfirmInfobarBannerInteractionHandlerTest, MainButton) {
handler_.MainButtonTapped(infobar_); handler_.MainButtonTapped(infobar_);
EXPECT_TRUE(infobar_->accepted()); EXPECT_TRUE(infobar_->accepted());
} }
// Tests that BannerVisibilityChanged() calls InfobarDismissed() on the mock
// delegate.
TEST_F(ConfirmInfobarBannerInteractionHandlerTest, UserInitiatedDismissal) {
EXPECT_CALL(mock_delegate(), InfoBarDismissed());
handler_.BannerDismissedByUser(infobar_);
}
...@@ -20,9 +20,6 @@ class PasswordInfobarBannerInteractionHandler ...@@ -20,9 +20,6 @@ class PasswordInfobarBannerInteractionHandler
// InfobarBannerInteractionHandler: // InfobarBannerInteractionHandler:
void BannerVisibilityChanged(InfoBarIOS* infobar, bool visible) override; void BannerVisibilityChanged(InfoBarIOS* infobar, bool visible) override;
void MainButtonTapped(InfoBarIOS* infobar) override; void MainButtonTapped(InfoBarIOS* infobar) override;
void ShowModalButtonTapped(InfoBarIOS* infobar,
web::WebState* web_state) override;
void BannerDismissedByUser(InfoBarIOS* infobar) override;
private: private:
// Returns the password delegate from |infobar|. // Returns the password delegate from |infobar|.
......
...@@ -41,32 +41,6 @@ void PasswordInfobarBannerInteractionHandler::MainButtonTapped( ...@@ -41,32 +41,6 @@ void PasswordInfobarBannerInteractionHandler::MainButtonTapped(
InfoBarIOS* infobar) { InfoBarIOS* infobar) {
infobar->set_accepted(GetInfobarDelegate(infobar)->Accept()); infobar->set_accepted(GetInfobarDelegate(infobar)->Accept());
} }
void PasswordInfobarBannerInteractionHandler::ShowModalButtonTapped(
InfoBarIOS* infobar,
web::WebState* web_state) {
InsertParams params(infobar);
params.infobar = infobar;
params.overlay_type = InfobarOverlayType::kModal;
params.insertion_index = OverlayRequestQueue::FromWebState(
web_state, OverlayModality::kInfobarModal)
->size();
params.source = InfobarOverlayInsertionSource::kBanner;
InfobarOverlayRequestInserter::FromWebState(web_state)->InsertOverlayRequest(
params);
}
void PasswordInfobarBannerInteractionHandler::BannerDismissedByUser(
InfoBarIOS* infobar) {
// Notify the delegate that a user-initiated dismissal has been triggered.
// NOTE: InfoBarDismissed() (camel cased) is used to notify the delegate that
// the user initiated the upcoming dismissal (i.e. swiped to dismiss in the
// refresh UI). InfobarDismissed() (not camel cased) is called in
// BannerVisibilityChanged() to notify the delegate of the dismissal of the
// UI.
GetInfobarDelegate(infobar)->InfoBarDismissed();
}
#pragma mark - Private #pragma mark - Private
IOSChromeSavePasswordInfoBarDelegate* IOSChromeSavePasswordInfoBarDelegate*
......
...@@ -72,23 +72,3 @@ TEST_F(PasswordInfobarBannerInteractionHandlerTest, MainButton) { ...@@ -72,23 +72,3 @@ TEST_F(PasswordInfobarBannerInteractionHandlerTest, MainButton) {
handler_.MainButtonTapped(infobar_); handler_.MainButtonTapped(infobar_);
EXPECT_TRUE(infobar_->accepted()); EXPECT_TRUE(infobar_->accepted());
} }
// Tests that pressing the modal button calls adds an OverlayRequest for the
// modal UI to the WebState's queue at OverlayModality::kInfobarModal.
TEST_F(PasswordInfobarBannerInteractionHandlerTest, ShowModal) {
OverlayRequestQueue* queue = OverlayRequestQueue::FromWebState(
&web_state_, OverlayModality::kInfobarModal);
ASSERT_EQ(0U, queue->size());
handler_.ShowModalButtonTapped(infobar_, &web_state_);
OverlayRequest* modal_request = queue->front_request();
EXPECT_TRUE(modal_request);
EXPECT_EQ(infobar_, GetOverlayRequestInfobar(modal_request));
}
// Tests that BannerVisibilityChanged() calls InfobarPresenting() and
// InfobarDismissed() on the mock delegate.
TEST_F(PasswordInfobarBannerInteractionHandlerTest, UserInitiatedDismissal) {
EXPECT_CALL(mock_delegate(), InfoBarDismissed());
handler_.BannerDismissedByUser(infobar_);
}
...@@ -115,7 +115,6 @@ void TranslateOverlayTabHelper::TranslateInfoBarAdded(InfoBarIOS* infobar) { ...@@ -115,7 +115,6 @@ void TranslateOverlayTabHelper::TranslateInfoBarAdded(InfoBarIOS* infobar) {
void TranslateOverlayTabHelper::UpdateForWebStateDestroyed() { void TranslateOverlayTabHelper::UpdateForWebStateDestroyed() {
DCHECK(banner_queue_); DCHECK(banner_queue_);
DCHECK(inserter_);
banner_queue_ = nullptr; banner_queue_ = nullptr;
inserter_ = nullptr; inserter_ = nullptr;
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment