// Copyright 2014 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "content/browser/notifications/notification_event_dispatcher_impl.h"

#include <optional>

#include "base/functional/bind.h"
#include "base/functional/callback.h"
#include "base/functional/callback_helpers.h"
#include "base/notreached.h"
#include "build/build_config.h"
#include "content/browser/notifications/devtools_event_logging.h"
#include "content/browser/notifications/platform_notification_context_impl.h"
#include "content/browser/service_worker/service_worker_context_wrapper.h"
#include "content/browser/service_worker/service_worker_registration.h"
#include "content/public/browser/browser_context.h"
#include "content/public/browser/browser_task_traits.h"
#include "content/public/browser/browser_thread.h"
#include "content/public/browser/render_frame_host.h"
#include "content/public/browser/render_process_host.h"
#include "content/public/browser/storage_partition.h"
#include "content/public/browser/weak_document_ptr.h"
#include "content/public/common/persistent_notification_status.h"
#include "third_party/blink/public/common/notifications/platform_notification_data.h"
#include "third_party/blink/public/common/storage_key/storage_key.h"

namespace content {
namespace {

using NotificationDispatchCompleteCallback =
    base::OnceCallback<void(PersistentNotificationStatus,
                            blink::ServiceWorkerStatusCode)>;
using PersistentNotificationDispatchCompleteCallback =
    base::OnceCallback<void(PersistentNotificationStatus)>;
using NotificationOperationCallback =
    base::OnceCallback<void(const ServiceWorkerRegistration*,
                            const NotificationDatabaseData&,
                            NotificationDispatchCompleteCallback)>;
using NotificationOperationCallbackWithContext =
    base::OnceCallback<void(const scoped_refptr<PlatformNotificationContext>&,
                            BrowserContext* browser_context,
                            const ServiceWorkerRegistration*,
                            const NotificationDatabaseData&,
                            NotificationDispatchCompleteCallback)>;

// Derives a PersistentNotificationStatus from the ServiceWorkerStatusCode.
PersistentNotificationStatus ConvertServiceWorkerStatus(
    blink::ServiceWorkerStatusCode service_worker_status) {
#if BUILDFLAG(IS_ANDROID)
  // This LOG(INFO) deliberately exists to help track down the cause of
  // https://crbug.com/534537, where notifications sometimes do not react to
  // the user clicking on them. It should be removed once that's fixed.
  LOG(INFO) << "The notification event has finished: "
            << blink::ServiceWorkerStatusToString(service_worker_status);
#endif
  switch (service_worker_status) {
    case blink::ServiceWorkerStatusCode::kOk:
      return PersistentNotificationStatus::kSuccess;
    case blink::ServiceWorkerStatusCode::kErrorEventWaitUntilRejected:
      return PersistentNotificationStatus::kWaitUntilRejected;
    case blink::ServiceWorkerStatusCode::kErrorFailed:
    case blink::ServiceWorkerStatusCode::kErrorAbort:
    case blink::ServiceWorkerStatusCode::kErrorStartWorkerFailed:
    case blink::ServiceWorkerStatusCode::kErrorProcessNotFound:
    case blink::ServiceWorkerStatusCode::kErrorNotFound:
    case blink::ServiceWorkerStatusCode::kErrorExists:
    case blink::ServiceWorkerStatusCode::kErrorInstallWorkerFailed:
    case blink::ServiceWorkerStatusCode::kErrorActivateWorkerFailed:
    case blink::ServiceWorkerStatusCode::kErrorIpcFailed:
    case blink::ServiceWorkerStatusCode::kErrorNetwork:
    case blink::ServiceWorkerStatusCode::kErrorSecurity:
    case blink::ServiceWorkerStatusCode::kErrorState:
    case blink::ServiceWorkerStatusCode::kErrorTimeout:
    case blink::ServiceWorkerStatusCode::kErrorScriptEvaluateFailed:
    case blink::ServiceWorkerStatusCode::kErrorDiskCache:
    case blink::ServiceWorkerStatusCode::kErrorRedundant:
    case blink::ServiceWorkerStatusCode::kErrorDisallowed:
    case blink::ServiceWorkerStatusCode::kErrorInvalidArguments:
    case blink::ServiceWorkerStatusCode::kErrorStorageDisconnected:
    case blink::ServiceWorkerStatusCode::kErrorStorageDataCorrupted:
      return PersistentNotificationStatus::kServiceWorkerError;
  }
  NOTREACHED();
}

// To be called when a notification event has finished with a
// blink::ServiceWorkerStatusCode result. Will run or post a task to call
// |dispatch_complete_callback| on the UI thread with a
// PersistentNotificationStatus derived from the service worker status.
void ServiceWorkerNotificationEventFinished(
    NotificationDispatchCompleteCallback dispatch_complete_callback,
    blink::ServiceWorkerStatusCode service_worker_status) {
  DCHECK_CURRENTLY_ON(BrowserThread::UI);
  std::move(dispatch_complete_callback)
      .Run(ConvertServiceWorkerStatus(service_worker_status),
           service_worker_status);
}

// Dispatches the given notification action event on
// |service_worker_registration| if the registration was available.
void DispatchNotificationEventOnRegistration(
    const NotificationDatabaseData& notification_database_data,
    NotificationOperationCallback dispatch_event_action,
    NotificationDispatchCompleteCallback dispatch_complete_callback,
    blink::ServiceWorkerStatusCode service_worker_status,
    scoped_refptr<ServiceWorkerRegistration> service_worker_registration) {
  DCHECK_CURRENTLY_ON(BrowserThread::UI);
#if BUILDFLAG(IS_ANDROID)
  // This LOG(INFO) deliberately exists to help track down the cause of
  // https://crbug.com/534537, where notifications sometimes do not react to
  // the user clicking on them. It should be removed once that's fixed.
  LOG(INFO) << "Trying to dispatch notification for SW with status: "
            << blink::ServiceWorkerStatusToString(service_worker_status);
#endif
  if (service_worker_status == blink::ServiceWorkerStatusCode::kOk) {
    DCHECK(service_worker_registration->active_version());

    std::move(dispatch_event_action)
        .Run(service_worker_registration.get(), notification_database_data,
             std::move(dispatch_complete_callback));
    return;
  }

  PersistentNotificationStatus status = PersistentNotificationStatus::kSuccess;
  switch (service_worker_status) {
    case blink::ServiceWorkerStatusCode::kErrorNotFound:
      status = PersistentNotificationStatus::kServiceWorkerMissing;
      break;
    case blink::ServiceWorkerStatusCode::kErrorFailed:
    case blink::ServiceWorkerStatusCode::kErrorAbort:
    case blink::ServiceWorkerStatusCode::kErrorStartWorkerFailed:
    case blink::ServiceWorkerStatusCode::kErrorProcessNotFound:
    case blink::ServiceWorkerStatusCode::kErrorExists:
    case blink::ServiceWorkerStatusCode::kErrorInstallWorkerFailed:
    case blink::ServiceWorkerStatusCode::kErrorActivateWorkerFailed:
    case blink::ServiceWorkerStatusCode::kErrorIpcFailed:
    case blink::ServiceWorkerStatusCode::kErrorNetwork:
    case blink::ServiceWorkerStatusCode::kErrorSecurity:
    case blink::ServiceWorkerStatusCode::kErrorEventWaitUntilRejected:
    case blink::ServiceWorkerStatusCode::kErrorState:
    case blink::ServiceWorkerStatusCode::kErrorTimeout:
    case blink::ServiceWorkerStatusCode::kErrorScriptEvaluateFailed:
    case blink::ServiceWorkerStatusCode::kErrorDiskCache:
    case blink::ServiceWorkerStatusCode::kErrorRedundant:
    case blink::ServiceWorkerStatusCode::kErrorDisallowed:
    case blink::ServiceWorkerStatusCode::kErrorInvalidArguments:
    case blink::ServiceWorkerStatusCode::kErrorStorageDisconnected:
    case blink::ServiceWorkerStatusCode::kErrorStorageDataCorrupted:
      status = PersistentNotificationStatus::kServiceWorkerError;
      break;
    case blink::ServiceWorkerStatusCode::kOk:
      NOTREACHED();
  }

  GetUIThreadTaskRunner({})->PostTask(
      FROM_HERE, base::BindOnce(std::move(dispatch_complete_callback), status,
                                service_worker_status));
}

// Finds the ServiceWorkerRegistration associated with the |origin| and
// |service_worker_registration_id|. Must be called on the UI thread.
void FindServiceWorkerRegistration(
    const url::Origin& origin,
    const scoped_refptr<ServiceWorkerContextWrapper>& service_worker_context,
    NotificationOperationCallback notification_action_callback,
    NotificationDispatchCompleteCallback dispatch_complete_callback,
    bool success,
    const NotificationDatabaseData& notification_database_data) {
  DCHECK_CURRENTLY_ON(BrowserThread::UI);
#if BUILDFLAG(IS_ANDROID)
  // This LOG(INFO) deliberately exists to help track down the cause of
  // https://crbug.com/534537, where notifications sometimes do not react to
  // the user clicking on them. It should be removed once that's fixed.
  LOG(INFO) << "Lookup for ServiceWoker Registration: success: " << success;
#endif
  if (!success) {
    std::move(dispatch_complete_callback)
        .Run(PersistentNotificationStatus::kDatabaseError,
             blink::ServiceWorkerStatusCode::kOk);
    return;
  }

  // If Push Notification becomes usable from a 3p context then
  // NotificationDatabaseData should be changed to use StorageKey.
  service_worker_context->FindReadyRegistrationForId(
      notification_database_data.service_worker_registration_id,
      blink::StorageKey::CreateFirstParty(origin),
      base::BindOnce(&DispatchNotificationEventOnRegistration,
                     notification_database_data,
                     std::move(notification_action_callback),
                     std::move(dispatch_complete_callback)));
}

// Reads the data associated with the |notification_id| belonging to |origin|
// from the notification context.
void ReadNotificationDatabaseData(
    const std::string& notification_id,
    const GURL& origin,
    PlatformNotificationContext::Interaction interaction,
    const scoped_refptr<ServiceWorkerContextWrapper>& service_worker_context,
    const scoped_refptr<PlatformNotificationContext>& notification_context,
    NotificationOperationCallback notification_read_callback,
    NotificationDispatchCompleteCallback dispatch_complete_callback) {
  DCHECK_CURRENTLY_ON(BrowserThread::UI);
  notification_context->ReadNotificationDataAndRecordInteraction(
      notification_id, origin, interaction,
      base::BindOnce(&FindServiceWorkerRegistration,
                     url::Origin::Create(origin), service_worker_context,
                     std::move(notification_read_callback),
                     std::move(dispatch_complete_callback)));
}

// -----------------------------------------------------------------------------

// Dispatches the notificationclick event on |service_worker|.
void DispatchNotificationClickEventOnWorker(
    const scoped_refptr<ServiceWorkerVersion>& service_worker,
    const NotificationDatabaseData& notification_database_data,
    const std::optional<int>& action_index,
    const std::optional<std::u16string>& reply,
    ServiceWorkerVersion::StatusCallback callback,
    blink::ServiceWorkerStatusCode start_worker_status) {
  DCHECK_CURRENTLY_ON(BrowserThread::UI);
  if (start_worker_status != blink::ServiceWorkerStatusCode::kOk) {
    std::move(callback).Run(start_worker_status);
    return;
  }

  int request_id = service_worker->StartRequest(
      ServiceWorkerMetrics::EventType::NOTIFICATION_CLICK, std::move(callback));

  int action_index_int = -1 /* no value */;
  if (action_index.has_value())
    action_index_int = action_index.value();

  service_worker->endpoint()->DispatchNotificationClickEvent(
      notification_database_data.notification_id,
      notification_database_data.notification_data, action_index_int, reply,
      service_worker->CreateSimpleEventCallback(request_id));
}

// Dispatches the notification click event on the |service_worker_registration|.
void DoDispatchNotificationClickEvent(
    const std::optional<int>& action_index,
    const std::optional<std::u16string>& reply,
    const scoped_refptr<PlatformNotificationContext>& notification_context,
    BrowserContext* browser_context,
    const ServiceWorkerRegistration* service_worker_registration,
    const NotificationDatabaseData& notification_database_data,
    NotificationDispatchCompleteCallback dispatch_complete_callback) {
  DCHECK_CURRENTLY_ON(BrowserThread::UI);

  notifications::LogNotificationClickedEventToDevTools(
      browser_context, notification_database_data, action_index, reply);

  service_worker_registration->active_version()->RunAfterStartWorker(
      ServiceWorkerMetrics::EventType::NOTIFICATION_CLICK,
      base::BindOnce(
          &DispatchNotificationClickEventOnWorker,
          base::WrapRefCounted(service_worker_registration->active_version()),
          notification_database_data, action_index, reply,
          base::BindOnce(&ServiceWorkerNotificationEventFinished,
                         std::move(dispatch_complete_callback))));
}

// -----------------------------------------------------------------------------

// Called when the notification data has been deleted to finish the notification
// close event.
void OnPersistentNotificationDataDeleted(
    blink::ServiceWorkerStatusCode service_worker_status,
    NotificationDispatchCompleteCallback dispatch_complete_callback,
    bool success) {
  DCHECK_CURRENTLY_ON(BrowserThread::UI);
  PersistentNotificationStatus status =
      success ? PersistentNotificationStatus::kSuccess
              : PersistentNotificationStatus::kDatabaseError;
  if (service_worker_status != blink::ServiceWorkerStatusCode::kOk)
    status = ConvertServiceWorkerStatus(service_worker_status);
  std::move(dispatch_complete_callback).Run(status, service_worker_status);
}

// Called when the persistent notification close event has been handled
// to remove the notification from the database.
void DeleteNotificationDataFromDatabase(
    const std::string& notification_id,
    const GURL& origin,
    const scoped_refptr<PlatformNotificationContext>& notification_context,
    NotificationDispatchCompleteCallback dispatch_complete_callback,
    blink::ServiceWorkerStatusCode status_code) {
  DCHECK_CURRENTLY_ON(BrowserThread::UI);
  notification_context->DeleteNotificationData(
      notification_id, origin,
      /* close_notification= */ false,
      base::BindOnce(&OnPersistentNotificationDataDeleted, status_code,
                     std::move(dispatch_complete_callback)));
}

// Dispatches the notificationclose event on |service_worker|.
void DispatchNotificationCloseEventOnWorker(
    const scoped_refptr<ServiceWorkerVersion>& service_worker,
    const NotificationDatabaseData& notification_database_data,
    ServiceWorkerVersion::StatusCallback callback,
    blink::ServiceWorkerStatusCode start_worker_status) {
  DCHECK_CURRENTLY_ON(BrowserThread::UI);
  if (start_worker_status != blink::ServiceWorkerStatusCode::kOk) {
    std::move(callback).Run(start_worker_status);
    return;
  }

  int request_id = service_worker->StartRequest(
      ServiceWorkerMetrics::EventType::NOTIFICATION_CLOSE, std::move(callback));

  service_worker->endpoint()->DispatchNotificationCloseEvent(
      notification_database_data.notification_id,
      notification_database_data.notification_data,
      service_worker->CreateSimpleEventCallback(request_id));
}

// Dispatches the notification close event on the service worker registration.
void DoDispatchNotificationCloseEvent(
    const std::string& notification_id,
    bool by_user,
    const scoped_refptr<PlatformNotificationContext>& notification_context,
    BrowserContext* browser_context,
    const ServiceWorkerRegistration* service_worker_registration,
    const NotificationDatabaseData& notification_database_data,
    NotificationDispatchCompleteCallback dispatch_complete_callback) {
  DCHECK_CURRENTLY_ON(BrowserThread::UI);
  if (by_user) {
    service_worker_registration->active_version()->RunAfterStartWorker(
        ServiceWorkerMetrics::EventType::NOTIFICATION_CLOSE,
        base::BindOnce(
            &DispatchNotificationCloseEventOnWorker,
            base::WrapRefCounted(service_worker_registration->active_version()),
            notification_database_data,
            base::BindOnce(&DeleteNotificationDataFromDatabase, notification_id,
                           notification_database_data.origin,
                           notification_context,
                           std::move(dispatch_complete_callback))));
  } else {
    DeleteNotificationDataFromDatabase(
        notification_id, notification_database_data.origin,
        notification_context, std::move(dispatch_complete_callback),
        blink::ServiceWorkerStatusCode::kOk);
  }
}

// Dispatches any notification event. The actual, specific event dispatch should
// be done by the |notification_action_callback|.
void DispatchNotificationEvent(
    BrowserContext* browser_context,
    const std::string& notification_id,
    const GURL& origin,
    const PlatformNotificationContext::Interaction interaction,
    NotificationOperationCallbackWithContext notification_action_callback,
    NotificationDispatchCompleteCallback dispatch_complete_callback) {
  DCHECK_CURRENTLY_ON(BrowserThread::UI);
  DCHECK(!notification_id.empty());
  DCHECK(origin.is_valid());

  StoragePartition* partition =
      browser_context->GetStoragePartitionForUrl(origin);

  scoped_refptr<ServiceWorkerContextWrapper> service_worker_context =
      static_cast<ServiceWorkerContextWrapper*>(
          partition->GetServiceWorkerContext());
  scoped_refptr<PlatformNotificationContext> notification_context =
      partition->GetPlatformNotificationContext();

  ReadNotificationDatabaseData(
      notification_id, origin, interaction, service_worker_context,
      notification_context,
      base::BindOnce(std::move(notification_action_callback),
                     notification_context, browser_context),
      std::move(dispatch_complete_callback));
}

void OnDispatchNotificationClickEventComplete(
    PersistentNotificationDispatchCompleteCallback dispatch_complete_callback,
    PersistentNotificationStatus status,
    blink::ServiceWorkerStatusCode service_worker_status) {
  std::move(dispatch_complete_callback).Run(status);
}

void OnDispatchNotificationCloseEventComplete(
    PersistentNotificationDispatchCompleteCallback dispatch_complete_callback,
    PersistentNotificationStatus status,
    blink::ServiceWorkerStatusCode service_worker_status) {
  std::move(dispatch_complete_callback).Run(status);
}

}  // namespace

// static
NotificationEventDispatcher* NotificationEventDispatcher::GetInstance() {
  return NotificationEventDispatcherImpl::GetInstance();
}

NotificationEventDispatcherImpl*
NotificationEventDispatcherImpl::GetInstance() {
  DCHECK_CURRENTLY_ON(BrowserThread::UI);
  return base::Singleton<NotificationEventDispatcherImpl>::get();
}

NotificationEventDispatcherImpl::NotificationEventDispatcherImpl() = default;
NotificationEventDispatcherImpl::~NotificationEventDispatcherImpl() = default;

NotificationEventDispatcherImpl::NonPersistentNotificationListenerInfo::
    NonPersistentNotificationListenerInfo(
        mojo::Remote<blink::mojom::NonPersistentNotificationListener> remote,
        WeakDocumentPtr document,
        RenderProcessHost::NotificationServiceCreatorType creator_type)
    : remote(std::move(remote)),
      document(document),
      creator_type(creator_type) {}

NotificationEventDispatcherImpl::NonPersistentNotificationListenerInfo::
    NonPersistentNotificationListenerInfo(
        NotificationEventDispatcherImpl::NonPersistentNotificationListenerInfo&&
            info) = default;

NotificationEventDispatcherImpl::NonPersistentNotificationListenerInfo::
    ~NonPersistentNotificationListenerInfo() = default;

base::optional_ref<content::NotificationEventDispatcherImpl::
                       NonPersistentNotificationListenerInfo>
NotificationEventDispatcherImpl::GetListenerIfNotifiable(
    const std::string& notification_id) {
  auto listener = non_persistent_notification_listeners_.find(notification_id);

  // If there is no listener registered for this notification id, no event
  // should be dispatched.
  if (listener == non_persistent_notification_listeners_.end()) {
    return std::nullopt;
  }

  // The non-persistent notification should not be created by service workers.
  DCHECK(listener->second.creator_type !=
         RenderProcessHost::NotificationServiceCreatorType::kServiceWorker);

  RenderFrameHost* rfh = listener->second.document.AsRenderFrameHostIfValid();
  if (!rfh) {
    switch (listener->second.creator_type) {
      case RenderProcessHost::NotificationServiceCreatorType::kDedicatedWorker:
      case RenderProcessHost::NotificationServiceCreatorType::kDocument: {
        // The weak document pointer should be pointing to the document that the
        // notification service is communicating with, if it's empty, it's
        // possible that the document is already destroyed. In this case, the
        // notification event shouldn't be dispatched.
        return std::nullopt;
      }
      case RenderProcessHost::NotificationServiceCreatorType::kSharedWorker: {
        // In this case, the weak document pointer is always null and we
        // shouldn't block the notification.
        return listener->second;
      }
      case RenderProcessHost::NotificationServiceCreatorType::kServiceWorker: {
        NOTREACHED();
      }
    }
  }

  // If the associated document is currently in back/forward cache, the
  // function returns nullopt to prevent the listener from being triggered.
  // TODO: in the future, this could be improved to cover more lifecycle
  // state. see: https://crrev.com/c/3861889/comment/e1759c1e_4dd15e4e/
  if (rfh->IsInLifecycleState(
          RenderFrameHost::LifecycleState::kInBackForwardCache)) {
    return std::nullopt;
  }
  return listener->second;
}

void NotificationEventDispatcherImpl::DispatchNotificationClickEvent(
    BrowserContext* browser_context,
    const std::string& notification_id,
    const GURL& origin,
    const std::optional<int>& action_index,
    const std::optional<std::u16string>& reply,
    NotificationDispatchCompleteCallback dispatch_complete_callback) {
  DCHECK_CURRENTLY_ON(BrowserThread::UI);

  PlatformNotificationContext::Interaction interaction =
      action_index.has_value()
          ? PlatformNotificationContext::Interaction::ACTION_BUTTON_CLICKED
          : PlatformNotificationContext::Interaction::CLICKED;

  DispatchNotificationEvent(
      browser_context, notification_id, origin, interaction,
      base::BindOnce(&DoDispatchNotificationClickEvent, action_index, reply),
      base::BindOnce(&OnDispatchNotificationClickEventComplete,
                     std::move(dispatch_complete_callback)));
}

void NotificationEventDispatcherImpl::DispatchNotificationCloseEvent(
    BrowserContext* browser_context,
    const std::string& notification_id,
    const GURL& origin,
    bool by_user,
    NotificationDispatchCompleteCallback dispatch_complete_callback) {
  DCHECK_CURRENTLY_ON(BrowserThread::UI);

  DispatchNotificationEvent(
      browser_context, notification_id, origin,
      PlatformNotificationContext::Interaction::CLOSED,
      base::BindOnce(&DoDispatchNotificationCloseEvent, notification_id,
                     by_user),
      base::BindOnce(&OnDispatchNotificationCloseEventComplete,
                     std::move(dispatch_complete_callback)));
}

void NotificationEventDispatcherImpl::RegisterNonPersistentNotificationListener(
    const std::string& notification_id,
    mojo::PendingRemote<blink::mojom::NonPersistentNotificationListener>
        event_listener_remote,
    const WeakDocumentPtr& event_document_ptr,
    const RenderProcessHost::NotificationServiceCreatorType creator_type) {
  mojo::Remote<blink::mojom::NonPersistentNotificationListener> bound_remote(
      std::move(event_listener_remote));

  // Observe connection errors, which occur when the JavaScript object or the
  // renderer hosting them goes away. (For example through navigation.) The
  // listener gets freed together with |this|, thus the Unretained is safe.
  bound_remote.set_disconnect_handler(base::BindOnce(
      &NotificationEventDispatcherImpl::
          HandleConnectionErrorForNonPersistentNotificationListener,
      base::Unretained(this), notification_id));

  // Dispatch the close event for any previously displayed notification with
  // the same notification id. This happens whenever a non-persistent
  // notification is replaced (by creating another with the same tag), since
  // from the JavaScript point of view there will be two notification objects,
  // and the old one needs to receive a close event before the new one
  // receives a show event.
  DispatchNonPersistentCloseEvent(notification_id, base::DoNothing());

  if (non_persistent_notification_listeners_.count(notification_id)) {
    non_persistent_notification_listeners_.erase(notification_id);
  }
  non_persistent_notification_listeners_.emplace(
      std::piecewise_construct, std::forward_as_tuple(notification_id),
      std::forward_as_tuple(std::move(bound_remote), event_document_ptr,
                            creator_type));
}

// Only fire the notification listeners (including show, click and
// close) when it exists in the map and the document is currently
// not in back/forward cache.
// See https://crbug.com/1350944
void NotificationEventDispatcherImpl::DispatchNonPersistentShowEvent(
    const std::string& notification_id) {
  auto listener = GetListenerIfNotifiable(notification_id);
  if (listener.has_value()) {
    listener->remote->OnShow();
  }
}

void NotificationEventDispatcherImpl::DispatchNonPersistentClickEvent(
    const std::string& notification_id,
    NotificationClickEventCallback callback) {
  auto listener = GetListenerIfNotifiable(notification_id);
  if (listener.has_value()) {
    listener->remote->OnClick(
        base::BindOnce(std::move(callback), true /* success */));
  } else {
    std::move(callback).Run(false /* success */);
  }
}

void NotificationEventDispatcherImpl::DispatchNonPersistentCloseEvent(
    const std::string& notification_id,
    base::OnceClosure completed_closure) {
  auto listener = GetListenerIfNotifiable(notification_id);
  if (listener.has_value()) {
    // Listeners get freed together with `this`, thus the Unretained is safe.
    listener->remote->OnClose(base::BindOnce(
        &NotificationEventDispatcherImpl::OnNonPersistentCloseComplete,
        base::Unretained(this), notification_id, std::move(completed_closure)));
  } else {
    std::move(completed_closure).Run();
  }
}

void NotificationEventDispatcherImpl::OnNonPersistentCloseComplete(
    const std::string& notification_id,
    base::OnceClosure completed_closure) {
  non_persistent_notification_listeners_.erase(notification_id);
  std::move(completed_closure).Run();
}

void NotificationEventDispatcherImpl::
    HandleConnectionErrorForNonPersistentNotificationListener(
        const std::string& notification_id) {
  DCHECK(non_persistent_notification_listeners_.count(notification_id));
  non_persistent_notification_listeners_.erase(notification_id);
}

}  // namespace content
