blob: 62cd4affae4d3b2f6fd7a314019aa277f817abe4 [file] [log] [blame]
// Copyright 2018 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/ui/autofill/local_card_migration_bubble_controller_impl.h"
#include <stddef.h>
#include "chrome/browser/autofill/strike_database_factory.h"
#include "chrome/browser/profiles/profile.h"
#include "chrome/browser/ui/autofill/local_card_migration_bubble.h"
#include "chrome/browser/ui/autofill/popup_constants.h"
#include "chrome/browser/ui/browser.h"
#include "chrome/browser/ui/browser_finder.h"
#include "chrome/browser/ui/browser_window.h"
#include "chrome/browser/ui/location_bar/location_bar.h"
#include "components/autofill/core/browser/autofill_metrics.h"
#include "components/autofill/core/browser/local_card_migration_strike_database.h"
#include "components/autofill/core/browser/strike_database.h"
#include "components/autofill/core/common/autofill_features.h"
#include "components/strings/grit/components_strings.h"
#include "content/public/browser/navigation_handle.h"
#include "ui/base/l10n/l10n_util.h"
namespace autofill {
// TODO(crbug.com/862405): Build a base class for this
// and SaveCardBubbleControllerImpl.
LocalCardMigrationBubbleControllerImpl::LocalCardMigrationBubbleControllerImpl(
content::WebContents* web_contents)
: content::WebContentsObserver(web_contents),
local_card_migration_bubble_(nullptr) {}
LocalCardMigrationBubbleControllerImpl::
~LocalCardMigrationBubbleControllerImpl() {
if (local_card_migration_bubble_)
HideBubble();
}
void LocalCardMigrationBubbleControllerImpl::ShowBubble(
base::OnceClosure local_card_migration_bubble_closure) {
// Don't show the bubble if it's already visible.
if (local_card_migration_bubble_)
return;
is_reshow_ = false;
local_card_migration_bubble_closure_ =
std::move(local_card_migration_bubble_closure);
AutofillMetrics::LogLocalCardMigrationBubbleOfferMetric(
AutofillMetrics::LOCAL_CARD_MIGRATION_BUBBLE_REQUESTED, is_reshow_);
ShowBubbleImplementation();
}
void LocalCardMigrationBubbleControllerImpl::HideBubble() {
if (local_card_migration_bubble_) {
local_card_migration_bubble_->Hide();
local_card_migration_bubble_ = nullptr;
}
}
void LocalCardMigrationBubbleControllerImpl::ReshowBubble() {
if (local_card_migration_bubble_)
return;
is_reshow_ = true;
AutofillMetrics::LogLocalCardMigrationBubbleOfferMetric(
AutofillMetrics::LOCAL_CARD_MIGRATION_BUBBLE_REQUESTED, is_reshow_);
ShowBubbleImplementation();
}
void LocalCardMigrationBubbleControllerImpl::AddObserver(
LocalCardMigrationControllerObserver* observer) {
observer_list_.AddObserver(observer);
}
LocalCardMigrationBubble*
LocalCardMigrationBubbleControllerImpl::local_card_migration_bubble_view()
const {
return local_card_migration_bubble_;
}
void LocalCardMigrationBubbleControllerImpl::OnConfirmButtonClicked() {
DCHECK(local_card_migration_bubble_closure_);
std::move(local_card_migration_bubble_closure_).Run();
should_add_strikes_on_bubble_close_ = false;
AutofillMetrics::LogLocalCardMigrationBubbleUserInteractionMetric(
AutofillMetrics::LOCAL_CARD_MIGRATION_BUBBLE_CLOSED_ACCEPTED, is_reshow_);
}
void LocalCardMigrationBubbleControllerImpl::OnCancelButtonClicked() {
local_card_migration_bubble_closure_.Reset();
AutofillMetrics::LogLocalCardMigrationBubbleUserInteractionMetric(
AutofillMetrics::LOCAL_CARD_MIGRATION_BUBBLE_CLOSED_DENIED, is_reshow_);
}
void LocalCardMigrationBubbleControllerImpl::OnBubbleClosed() {
local_card_migration_bubble_ = nullptr;
UpdateIcon();
if (should_add_strikes_on_bubble_close_ &&
base::FeatureList::IsEnabled(
features::kAutofillSaveCreditCardUsesStrikeSystemV2) &&
base::FeatureList::IsEnabled(
features::kAutofillLocalCardMigrationUsesStrikeSystemV2)) {
should_add_strikes_on_bubble_close_ = false;
AddStrikesForBubbleClose();
}
}
base::TimeDelta LocalCardMigrationBubbleControllerImpl::Elapsed() const {
return timer_->Elapsed();
}
void LocalCardMigrationBubbleControllerImpl::DidFinishNavigation(
content::NavigationHandle* navigation_handle) {
if (!navigation_handle->IsInMainFrame() || !navigation_handle->HasCommitted())
return;
// Nothing to do if there's no bubble available.
if (!local_card_migration_bubble_closure_)
return;
// Don't react to same-document (fragment) navigations.
if (navigation_handle->IsSameDocument())
return;
// Don't do anything if a navigation occurs before a user could reasonably
// interact with the bubble.
if (Elapsed() < kCardBubbleSurviveNavigationTime)
return;
// Otherwise, get rid of the bubble and icon.
local_card_migration_bubble_closure_.Reset();
bool bubble_was_visible = local_card_migration_bubble_;
for (LocalCardMigrationControllerObserver& observer : observer_list_) {
observer.OnMigrationNoLongerAvailable();
}
if (bubble_was_visible) {
local_card_migration_bubble_->Hide();
OnBubbleClosed();
} else {
UpdateIcon();
}
AutofillMetrics::LogLocalCardMigrationBubbleUserInteractionMetric(
bubble_was_visible
? AutofillMetrics::
LOCAL_CARD_MIGRATION_BUBBLE_CLOSED_NAVIGATED_WHILE_SHOWING
: AutofillMetrics::
LOCAL_CARD_MIGRATION_BUBBLE_CLOSED_NAVIGATED_WHILE_HIDDEN,
is_reshow_);
}
void LocalCardMigrationBubbleControllerImpl::OnVisibilityChanged(
content::Visibility visibility) {
if (visibility == content::Visibility::HIDDEN)
HideBubble();
}
void LocalCardMigrationBubbleControllerImpl::WebContentsDestroyed() {
HideBubble();
}
void LocalCardMigrationBubbleControllerImpl::ShowBubbleImplementation() {
DCHECK(local_card_migration_bubble_closure_);
DCHECK(!local_card_migration_bubble_);
// Need to create location bar icon before bubble, otherwise bubble will be
// unanchored.
UpdateIcon();
Browser* browser = chrome::FindBrowserWithWebContents(web_contents());
local_card_migration_bubble_ =
browser->window()->ShowLocalCardMigrationBubble(web_contents(), this,
is_reshow_);
DCHECK(local_card_migration_bubble_);
UpdateIcon();
timer_.reset(new base::ElapsedTimer());
AutofillMetrics::LogLocalCardMigrationBubbleOfferMetric(
AutofillMetrics::LOCAL_CARD_MIGRATION_BUBBLE_SHOWN, is_reshow_);
}
void LocalCardMigrationBubbleControllerImpl::UpdateIcon() {
Browser* browser = chrome::FindBrowserWithWebContents(web_contents());
if (!browser)
return;
LocationBar* location_bar = browser->window()->GetLocationBar();
if (!location_bar)
return;
location_bar->UpdateLocalCardMigrationIcon();
}
void LocalCardMigrationBubbleControllerImpl::AddStrikesForBubbleClose() {
LocalCardMigrationStrikeDatabase local_card_migration_strike_database(
StrikeDatabaseFactory::GetForProfile(
Profile::FromBrowserContext(web_contents()->GetBrowserContext())));
local_card_migration_strike_database.AddStrikes(
LocalCardMigrationStrikeDatabase::kStrikesToAddWhenBubbleClosed);
}
WEB_CONTENTS_USER_DATA_KEY_IMPL(LocalCardMigrationBubbleControllerImpl)
} // namespace autofill