[go: nahoru, domu]

blob: 3da09adeaed563763a81d2ebf80479b8c71f8a9b [file] [log] [blame]
// Copyright 2019 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/platform_notification_service_proxy.h"
#include <memory>
#include <utility>
#include "base/check_op.h"
#include "content/browser/notifications/devtools_event_logging.h"
#include "content/browser/service_worker/service_worker_context_wrapper.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/notification_database_data.h"
#include "content/public/browser/platform_notification_service.h"
#include "content/public/common/content_client.h"
#include "third_party/blink/public/common/storage_key/storage_key.h"
namespace content {
PlatformNotificationServiceProxy::PlatformNotificationServiceProxy(
scoped_refptr<ServiceWorkerContextWrapper> service_worker_context,
BrowserContext* browser_context)
: service_worker_context_(service_worker_context),
browser_context_(browser_context),
notification_service_(browser_context->GetPlatformNotificationService()) {
}
PlatformNotificationServiceProxy::~PlatformNotificationServiceProxy() = default;
void PlatformNotificationServiceProxy::Shutdown() {
DCHECK_CURRENTLY_ON(BrowserThread::UI);
weak_ptr_factory_ui_.InvalidateWeakPtrs();
}
base::WeakPtr<PlatformNotificationServiceProxy>
PlatformNotificationServiceProxy::AsWeakPtr() {
return weak_ptr_factory_ui_.GetWeakPtr();
}
void PlatformNotificationServiceProxy::DoDisplayNotification(
const NotificationDatabaseData& data,
const GURL& service_worker_scope,
DisplayResultCallback callback) {
DCHECK_CURRENTLY_ON(BrowserThread::UI);
if (notification_service_) {
notification_service_->DisplayPersistentNotification(
data.notification_id, service_worker_scope, data.origin,
data.notification_data,
data.notification_resources.value_or(blink::NotificationResources()));
notifications::LogNotificationDisplayedEventToDevTools(browser_context_,
data);
}
std::move(callback).Run(/* success= */ true, data.notification_id);
}
void PlatformNotificationServiceProxy::VerifyServiceWorkerScope(
const NotificationDatabaseData& data,
DisplayResultCallback callback,
blink::ServiceWorkerStatusCode status,
scoped_refptr<ServiceWorkerRegistration> registration) {
DCHECK_CURRENTLY_ON(BrowserThread::UI);
base::OnceClosure task;
if (status == blink::ServiceWorkerStatusCode::kOk &&
registration->key().origin().GetURL() == data.origin) {
DoDisplayNotification(data, registration->scope(), std::move(callback));
} else {
std::move(callback).Run(/* success= */ false, /* notification_id= */ "");
}
}
void PlatformNotificationServiceProxy::DisplayNotification(
const NotificationDatabaseData& data,
DisplayResultCallback callback) {
if (!service_worker_context_) {
GetUIThreadTaskRunner({base::TaskPriority::USER_VISIBLE})
->PostTask(FROM_HERE,
base::BindOnce(
&PlatformNotificationServiceProxy::DoDisplayNotification,
AsWeakPtr(), data, GURL(), std::move(callback)));
return;
}
GetUIThreadTaskRunner({base::TaskPriority::USER_VISIBLE})
->PostTask(
FROM_HERE,
base::BindOnce(
&ServiceWorkerContextWrapper::FindReadyRegistrationForId,
service_worker_context_, data.service_worker_registration_id,
blink::StorageKey::CreateFirstParty(
url::Origin::Create(data.origin)),
base::BindOnce(
&PlatformNotificationServiceProxy::VerifyServiceWorkerScope,
weak_ptr_factory_io_.GetWeakPtr(), data,
std::move(callback))));
}
void PlatformNotificationServiceProxy::CloseNotifications(
const std::set<std::string>& notification_ids) {
if (!notification_service_)
return;
GetUIThreadTaskRunner({base::TaskPriority::USER_VISIBLE})
->PostTask(FROM_HERE,
base::BindOnce(
&PlatformNotificationServiceProxy::DoCloseNotifications,
AsWeakPtr(), notification_ids));
}
void PlatformNotificationServiceProxy::DoCloseNotifications(
const std::set<std::string>& notification_ids) {
DCHECK_CURRENTLY_ON(BrowserThread::UI);
for (const std::string& notification_id : notification_ids)
notification_service_->ClosePersistentNotification(notification_id);
}
void PlatformNotificationServiceProxy::ScheduleTrigger(base::Time timestamp) {
if (!notification_service_)
return;
GetUIThreadTaskRunner({base::TaskPriority::USER_VISIBLE})
->PostTask(
FROM_HERE,
base::BindOnce(&PlatformNotificationServiceProxy::DoScheduleTrigger,
AsWeakPtr(), timestamp));
}
void PlatformNotificationServiceProxy::DoScheduleTrigger(base::Time timestamp) {
DCHECK_CURRENTLY_ON(BrowserThread::UI);
notification_service_->ScheduleTrigger(timestamp);
}
void PlatformNotificationServiceProxy::ScheduleNotification(
const NotificationDatabaseData& data) {
DCHECK(data.notification_data.show_trigger_timestamp.has_value());
if (!notification_service_)
return;
GetUIThreadTaskRunner({base::TaskPriority::USER_VISIBLE})
->PostTask(FROM_HERE,
base::BindOnce(
&PlatformNotificationServiceProxy::DoScheduleNotification,
AsWeakPtr(), data));
}
void PlatformNotificationServiceProxy::DoScheduleNotification(
const NotificationDatabaseData& data) {
DCHECK_CURRENTLY_ON(BrowserThread::UI);
base::Time show_trigger_timestamp =
data.notification_data.show_trigger_timestamp.value();
notifications::LogNotificationScheduledEventToDevTools(
browser_context_, data, show_trigger_timestamp);
notification_service_->ScheduleTrigger(show_trigger_timestamp);
}
base::Time PlatformNotificationServiceProxy::GetNextTrigger() {
DCHECK_CURRENTLY_ON(BrowserThread::UI);
if (!notification_service_)
return base::Time::Max();
return notification_service_->ReadNextTriggerTimestamp();
}
void PlatformNotificationServiceProxy::RecordNotificationUkmEvent(
const NotificationDatabaseData& data) {
DCHECK_CURRENTLY_ON(BrowserThread::UI);
if (!notification_service_)
return;
notification_service_->RecordNotificationUkmEvent(data);
}
bool PlatformNotificationServiceProxy::ShouldLogClose(const GURL& origin) {
DCHECK_CURRENTLY_ON(BrowserThread::UI);
return notifications::ShouldLogNotificationEventToDevTools(browser_context_,
origin);
}
void PlatformNotificationServiceProxy::LogClose(
const NotificationDatabaseData& data) {
GetUIThreadTaskRunner({base::TaskPriority::BEST_EFFORT})
->PostTask(FROM_HERE,
base::BindOnce(&PlatformNotificationServiceProxy::DoLogClose,
AsWeakPtr(), data));
}
void PlatformNotificationServiceProxy::DoLogClose(
const NotificationDatabaseData& data) {
DCHECK_CURRENTLY_ON(BrowserThread::UI);
notifications::LogNotificationClosedEventToDevTools(browser_context_, data);
}
} // namespace content