// Copyright 2021 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "components/webapps/browser/android/installable/installable_ambient_badge_message_controller.h"
#include "base/command_line.h"
#include "base/containers/lru_cache.h"
#include "base/functional/bind.h"
#include "base/no_destructor.h"
#include "components/messages/android/message_dispatcher_bridge.h"
#include "components/messages/android/throttler/domain_session_throttler.h"
#include "components/strings/grit/components_strings.h"
#include "components/url_formatter/elide_url.h"
#include "components/webapps/browser/android/installable/installable_ambient_badge_client.h"
#include "components/webapps/browser/android/webapps_icon_utils.h"
#include "components/webapps/browser/features.h"
#include "components/webapps/common/switches.h"
#include "content/public/browser/web_contents.h"
#include "ui/base/l10n/l10n_util.h"
namespace webapps {
namespace {
constexpr int kThrottleDomainsCapacity = 100;
}
InstallableAmbientBadgeMessageController::
InstallableAmbientBadgeMessageController(
InstallableAmbientBadgeClient* client)
: client_(client) {}
InstallableAmbientBadgeMessageController::
~InstallableAmbientBadgeMessageController() {
DismissMessage();
}
bool InstallableAmbientBadgeMessageController::IsMessageEnqueued() {
return message_ != nullptr;
}
void InstallableAmbientBadgeMessageController::EnqueueMessage(
content::WebContents* web_contents,
const std::u16string& app_name,
const SkBitmap& icon,
const bool is_primary_icon_maskable,
const GURL& start_url) {
DCHECK(!message_);
if (!base::CommandLine::ForCurrentProcess()->HasSwitch(
switches::kBypassInstallThrottleForTesting) &&
!GetThrottler()->ShouldShow(
web_contents->GetPrimaryMainFrame()->GetLastCommittedOrigin())) {
return;
}
save_origin_ = web_contents->GetPrimaryMainFrame()->GetLastCommittedOrigin();
message_ = std::make_unique<messages::MessageWrapper>(
messages::MessageIdentifier::INSTALLABLE_AMBIENT_BADGE,
base::BindOnce(
&InstallableAmbientBadgeMessageController::HandleInstallButtonClicked,
weak_factory_.GetWeakPtr()),
base::BindOnce(
&InstallableAmbientBadgeMessageController::HandleMessageDismissed,
weak_factory_.GetWeakPtr()));
message_->SetTitle(l10n_util::GetStringFUTF16(
IDS_AMBIENT_BADGE_INSTALL_ALTERNATIVE, app_name));
message_->SetDescription(url_formatter::FormatUrlForSecurityDisplay(
start_url, url_formatter::SchemeDisplay::OMIT_CRYPTOGRAPHIC));
message_->DisableIconTint();
if (is_primary_icon_maskable &&
WebappsIconUtils::DoesAndroidSupportMaskableIcons()) {
message_->SetIcon(WebappsIconUtils::GenerateAdaptiveIconBitmap(icon));
} else {
message_->SetIcon(icon);
}
message_->EnableLargeIcon(true);
message_->SetIconRoundedCornerRadius(
WebappsIconUtils::GetIdealIconCornerRadiusPxForPromptUI());
message_->SetPrimaryButtonText(l10n_util::GetStringUTF16(IDS_INSTALL));
messages::MessageDispatcherBridge::Get()->EnqueueMessage(
message_.get(), web_contents, messages::MessageScopeType::NAVIGATION,
messages::MessagePriority::kNormal);
}
void InstallableAmbientBadgeMessageController::DismissMessage() {
if (!message_)
return;
messages::MessageDispatcherBridge::Get()->DismissMessage(
message_.get(), messages::DismissReason::UNKNOWN);
}
void InstallableAmbientBadgeMessageController::HandleInstallButtonClicked() {
client_->AddToHomescreenFromBadge();
}
void InstallableAmbientBadgeMessageController::HandleMessageDismissed(
messages::DismissReason dismiss_reason) {
DCHECK(message_);
message_.reset();
if (dismiss_reason == messages::DismissReason::GESTURE) {
client_->BadgeDismissed();
} else if (dismiss_reason == messages::DismissReason::TIMER) {
client_->BadgeIgnored();
}
if (dismiss_reason != messages::DismissReason::PRIMARY_ACTION) {
GetThrottler()->AddStrike(save_origin_);
}
}
// static
messages::DomainSessionThrottler*
InstallableAmbientBadgeMessageController::GetThrottler() {
static messages::DomainSessionThrottler instance(kThrottleDomainsCapacity);
return &instance;
}
} // namespace webapps