Commit be1c7542 authored by Xing Liu's avatar Xing Liu Committed by Commit Bot

Notification scheduler: Adds client interface and registrar.

This CL adds the notification client interface, and a registrar class
to register and maintain ownership of clients.

The registrar is plumbed into the scheduler keyed service. The internal
code will hook to the client in a following CL.

Bug: 963288,930968
Change-Id: I48eb8cf460260304ab1ebd6de201a4ffc224ddc0
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/1616013
Commit-Queue: Xing Liu <xingliu@chromium.org>
Reviewed-by: default avatarDavid Trainor <dtrainor@chromium.org>
Cr-Commit-Position: refs/heads/master@{#664089}
parent 13a23e7c
......@@ -26,6 +26,9 @@ source_set("public") {
"notification_params.cc",
"notification_params.h",
"notification_schedule_service.h",
"notification_scheduler_client.h",
"notification_scheduler_client_registrar.cc",
"notification_scheduler_client_registrar.h",
"notification_scheduler_types.h",
"schedule_params.cc",
"schedule_params.h",
......@@ -35,6 +38,7 @@ source_set("public") {
deps = [
"//base",
"//components/keyed_service/core",
"//skia",
]
}
......@@ -112,6 +116,7 @@ source_set("lib") {
"//chrome/browser/notifications/proto",
"//components/keyed_service/core",
"//components/leveldb_proto",
"//skia",
]
}
......
......@@ -9,6 +9,7 @@
#include "chrome/browser/notifications/scheduler/notification_background_task_scheduler_impl.h"
#include "chrome/browser/notifications/scheduler/notification_schedule_service.h"
#include "chrome/browser/notifications/scheduler/notification_scheduler_client_registrar.h"
#include "chrome/browser/notifications/scheduler/notification_scheduler_context.h"
#include "chrome/browser/notifications/scheduler/schedule_service_factory_helper.h"
#include "chrome/browser/profiles/incognito_helpers.h"
......@@ -17,6 +18,18 @@
#include "components/keyed_service/content/browser_context_dependency_manager.h"
#include "components/leveldb_proto/content/proto_database_provider_factory.h"
namespace {
std::unique_ptr<notifications::NotificationSchedulerClientRegistrar>
RegisterClients() {
auto client_registrar =
std::make_unique<notifications::NotificationSchedulerClientRegistrar>();
// TODO(xingliu): Register clients here.
return client_registrar;
}
} // namespace
// static
NotificationScheduleServiceFactory*
NotificationScheduleServiceFactory::GetInstance() {
......@@ -47,12 +60,14 @@ KeyedService* NotificationScheduleServiceFactory::BuildServiceInstanceFor(
auto* profile = Profile::FromBrowserContext(context);
base::FilePath storage_dir =
profile->GetPath().Append(chrome::kNotificationSchedulerStorageDirname);
auto client_registrar = RegisterClients();
auto background_task_scheduler =
std::make_unique<NotificationBackgroundTaskSchedulerImpl>();
auto* db_provider = leveldb_proto::ProtoDatabaseProviderFactory::GetForKey(
profile->GetProfileKey());
return notifications::CreateNotificationScheduleService(
std::move(background_task_scheduler), db_provider, storage_dir);
std::move(client_registrar), std::move(background_task_scheduler),
db_provider, storage_dir);
}
content::BrowserContext*
......
......@@ -5,6 +5,7 @@
#include "chrome/browser/notifications/scheduler/notification_scheduler.h"
#include <utility>
#include <vector>
#include "base/bind.h"
#include "base/logging.h"
......@@ -17,6 +18,8 @@
#include "chrome/browser/notifications/scheduler/notification_background_task_scheduler.h"
#include "chrome/browser/notifications/scheduler/notification_entry.h"
#include "chrome/browser/notifications/scheduler/notification_params.h"
#include "chrome/browser/notifications/scheduler/notification_scheduler_client.h"
#include "chrome/browser/notifications/scheduler/notification_scheduler_client_registrar.h"
#include "chrome/browser/notifications/scheduler/notification_scheduler_context.h"
#include "chrome/browser/notifications/scheduler/scheduled_notification_manager.h"
......@@ -160,8 +163,11 @@ class NotificationSchedulerImpl
for (const auto& client_state : client_states) {
client_state_ptrs.emplace(client_state.first, client_state.second.get());
}
std::vector<SchedulerClientType> clients;
context_->client_registrar()->GetRegisteredClients(&clients);
context_->display_decider()->FindNotificationsToShow(
context_->config(), context_->clients(), DistributionPolicy::Create(),
context_->config(), std::move(clients), DistributionPolicy::Create(),
task_start_time, std::move(notifications), std::move(client_state_ptrs),
&results);
......
// Copyright 2019 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.
#ifndef CHROME_BROWSER_NOTIFICATIONS_SCHEDULER_NOTIFICATION_SCHEDULER_CLIENT_H_
#define CHROME_BROWSER_NOTIFICATIONS_SCHEDULER_NOTIFICATION_SCHEDULER_CLIENT_H_
#include <map>
#include <memory>
#include <set>
#include <string>
#include "base/callback.h"
#include "base/macros.h"
#include "base/optional.h"
#include "chrome/browser/notifications/scheduler/notification_data.h"
#include "chrome/browser/notifications/scheduler/notification_scheduler_types.h"
#include "third_party/skia/include/core/SkBitmap.h"
namespace notifications {
// The client interface to receive events from notification scheduler.
class NotificationSchedulerClient {
public:
struct DisplayData {
NotificationData notification_data;
SkBitmap icon;
};
// Defines user actions type.
enum class UserActionType {
// The user clicks on the notification body.
kClick = 0,
// The user clicks on the notification button.
kButtonClick = 1,
// The user dismisses the notification.
kDismiss = 2,
};
// Information about button clicks.
struct ButtonClickInfo {
// Unique id of the button.
std::string button_id;
// Associate impression type for the button.
ActionButtonType type = ActionButtonType::kUnknownAction;
};
using DisplayCallback =
base::OnceCallback<void(std::unique_ptr<DisplayData>)>;
NotificationSchedulerClient();
virtual ~NotificationSchedulerClient();
// Called when the notification should be displayed to the user. The clients
// can overwrite data in |display_data| and return the updated data in
// |callback|.
virtual void ShowNotification(std::unique_ptr<DisplayData> display_data,
DisplayCallback callback) = 0;
// Called when scheduler is initialized, number of notification scheduled for
// this type is reported if initialization succeeded.
virtual void OnSchedulerInitialized(bool success,
std::set<std::string> guids) = 0;
// Called when the user interacts with the notification.
virtual void OnUserAction(UserActionType action_type,
const std::string& notification_id,
base::Optional<ButtonClickInfo> button_info) = 0;
private:
DISALLOW_COPY_AND_ASSIGN(NotificationSchedulerClient);
};
} // namespace notifications
#endif // CHROME_BROWSER_NOTIFICATIONS_SCHEDULER_NOTIFICATION_SCHEDULER_CLIENT_H_
// Copyright 2019 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/notifications/scheduler/notification_scheduler_client_registrar.h"
#include <utility>
#include "base/logging.h"
#include "chrome/browser/notifications/scheduler/notification_scheduler_client.h"
namespace notifications {
NotificationSchedulerClientRegistrar::NotificationSchedulerClientRegistrar() =
default;
NotificationSchedulerClientRegistrar::~NotificationSchedulerClientRegistrar() =
default;
void NotificationSchedulerClientRegistrar::RegisterClient(
SchedulerClientType type,
std::unique_ptr<NotificationSchedulerClient> client) {
DCHECK(clients_.find(type) == clients_.end());
clients_.emplace(type, std::move(client));
}
NotificationSchedulerClient* NotificationSchedulerClientRegistrar::GetClient(
SchedulerClientType type) {
auto it = clients_.find(type);
if (it == clients_.end())
return nullptr;
return it->second.get();
}
void NotificationSchedulerClientRegistrar::GetRegisteredClients(
std::vector<SchedulerClientType>* clients) const {
DCHECK(clients);
clients->clear();
for (const auto& pair : clients_) {
clients->emplace_back(pair.first);
}
}
} // namespace notifications
// Copyright 2019 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.
#ifndef CHROME_BROWSER_NOTIFICATIONS_SCHEDULER_NOTIFICATION_SCHEDULER_CLIENT_REGISTRAR_H_
#define CHROME_BROWSER_NOTIFICATIONS_SCHEDULER_NOTIFICATION_SCHEDULER_CLIENT_REGISTRAR_H_
#include <map>
#include <memory>
#include <vector>
#include "base/macros.h"
#include "chrome/browser/notifications/scheduler/notification_scheduler_types.h"
namespace notifications {
class NotificationSchedulerClient;
// Registers and maintains a list of NotificationSchedulerClient
// implementations.
class NotificationSchedulerClientRegistrar {
public:
NotificationSchedulerClientRegistrar();
~NotificationSchedulerClientRegistrar();
// Registers a client into notification scheduler system.
void RegisterClient(SchedulerClientType type,
std::unique_ptr<NotificationSchedulerClient> client);
// Gets a NotificationSchedulerClient, nullptr if the type doesn't exist.
NotificationSchedulerClient* GetClient(SchedulerClientType type);
// Gets a list of registered clients, sorted by integer value of
// SchedulerClientType.
void GetRegisteredClients(std::vector<SchedulerClientType>* clients) const;
private:
using ClientsMap = std::map<SchedulerClientType,
std::unique_ptr<NotificationSchedulerClient>>;
ClientsMap clients_;
DISALLOW_COPY_AND_ASSIGN(NotificationSchedulerClientRegistrar);
};
} // namespace notifications
#endif // CHROME_BROWSER_NOTIFICATIONS_SCHEDULER_NOTIFICATION_SCHEDULER_CLIENT_REGISTRAR_H_
......@@ -10,19 +10,22 @@
#include "chrome/browser/notifications/scheduler/icon_store.h"
#include "chrome/browser/notifications/scheduler/impression_history_tracker.h"
#include "chrome/browser/notifications/scheduler/notification_background_task_scheduler.h"
#include "chrome/browser/notifications/scheduler/notification_scheduler_client_registrar.h"
#include "chrome/browser/notifications/scheduler/scheduled_notification_manager.h"
#include "chrome/browser/notifications/scheduler/scheduler_config.h"
namespace notifications {
NotificationSchedulerContext::NotificationSchedulerContext(
std::unique_ptr<NotificationSchedulerClientRegistrar> client_registrar,
std::unique_ptr<NotificationBackgroundTaskScheduler> scheduler,
std::unique_ptr<IconStore> icon_store,
std::unique_ptr<ImpressionHistoryTracker> impression_tracker,
std::unique_ptr<ScheduledNotificationManager> notification_manager,
std::unique_ptr<DisplayDecider> display_decider,
std::unique_ptr<SchedulerConfig> config)
: background_task_scheduler_(std::move(scheduler)),
: client_registrar_(std::move(client_registrar)),
background_task_scheduler_(std::move(scheduler)),
impression_tracker_(std::move(impression_tracker)),
notification_manager_(std::move(notification_manager)),
display_decider_(std::move(display_decider)),
......
......@@ -17,6 +17,7 @@ class DisplayDecider;
class IconStore;
class ImpressionHistoryTracker;
class NotificationBackgroundTaskScheduler;
class NotificationSchedulerClientRegistrar;
class ScheduledNotificationManager;
struct SchedulerConfig;
......@@ -25,6 +26,7 @@ struct SchedulerConfig;
class NotificationSchedulerContext {
public:
NotificationSchedulerContext(
std::unique_ptr<NotificationSchedulerClientRegistrar> client_registrar,
std::unique_ptr<NotificationBackgroundTaskScheduler> scheduler,
std::unique_ptr<IconStore> icon_store,
std::unique_ptr<ImpressionHistoryTracker> impression_tracker,
......@@ -33,7 +35,9 @@ class NotificationSchedulerContext {
std::unique_ptr<SchedulerConfig> config);
~NotificationSchedulerContext();
const std::vector<SchedulerClientType>& clients() const { return clients_; }
NotificationSchedulerClientRegistrar* client_registrar() {
return client_registrar_.get();
}
NotificationBackgroundTaskScheduler* background_task_scheduler() {
return background_task_scheduler_.get();
......@@ -54,9 +58,8 @@ class NotificationSchedulerContext {
const SchedulerConfig* config() const { return config_.get(); }
private:
// List of clients using the notification scheduler system.
// TODO(xingliu): Pass in the registered the clients.
std::vector<SchedulerClientType> clients_;
// Holds a list of clients using the notification scheduler system.
std::unique_ptr<NotificationSchedulerClientRegistrar> client_registrar_;
// Used to schedule background task in OS level.
std::unique_ptr<NotificationBackgroundTaskScheduler>
......
......@@ -52,7 +52,8 @@ enum class UserFeedback {
kMaxValue = kIgnore
};
// The user impression of a particular notification.
// The user impression of a particular notification, which may impact the
// notification display frenquency.
enum class ImpressionResult {
// Invalid user impression.
kInvalid = 0,
......@@ -65,6 +66,19 @@ enum class ImpressionResult {
kMaxValue = kNeutral
};
// Categorizes type of notification buttons. Different type of button clicks
// may result in change of notification shown frequency.
enum class ActionButtonType {
// The action button is not categorized.
kUnknownAction = 0,
// Helpful button indicates the user likes to interact with the notification.
kHelpful = 1,
// Unhelpful button indicates dislike of the notification.
kUnhelpful = 2,
};
} // namespace notifications
#endif // CHROME_BROWSER_NOTIFICATIONS_SCHEDULER_NOTIFICATION_SCHEDULER_TYPES_H_
......@@ -15,6 +15,7 @@
#include "chrome/browser/notifications/scheduler/init_aware_scheduler.h"
#include "chrome/browser/notifications/scheduler/notification_background_task_scheduler.h"
#include "chrome/browser/notifications/scheduler/notification_schedule_service_impl.h"
#include "chrome/browser/notifications/scheduler/notification_scheduler_client_registrar.h"
#include "chrome/browser/notifications/scheduler/notification_scheduler_context.h"
#include "chrome/browser/notifications/scheduler/notification_store.h"
#include "chrome/browser/notifications/scheduler/scheduled_notification_manager.h"
......@@ -32,6 +33,7 @@ const base::FilePath::CharType kNotificationDBName[] =
} // namespace
KeyedService* CreateNotificationScheduleService(
std::unique_ptr<NotificationSchedulerClientRegistrar> client_registrar,
std::unique_ptr<NotificationBackgroundTaskScheduler>
background_task_scheduler,
leveldb_proto::ProtoDatabaseProvider* db_provider,
......@@ -71,9 +73,10 @@ KeyedService* CreateNotificationScheduleService(
notification_manager->Create(std::move(notification_store));
auto context = std::make_unique<NotificationSchedulerContext>(
std::move(background_task_scheduler), std::move(icon_store),
std::move(impression_tracker), std::move(notification_manager),
DisplayDecider::Create(), std::move(config));
std::move(client_registrar), std::move(background_task_scheduler),
std::move(icon_store), std::move(impression_tracker),
std::move(notification_manager), DisplayDecider::Create(),
std::move(config));
auto scheduler = NotificationScheduler::Create(std::move(context));
auto init_aware_scheduler =
......
......@@ -18,11 +18,13 @@ class ProtoDatabaseProvider;
namespace notifications {
class NotificationBackgroundTaskScheduler;
class NotificationSchedulerClientRegistrar;
// Creates the notification schedule service with all the embedder level
// dependencies. This layer is mainly to forbid the embedder to depend on
// notification scheduler internal code.
KeyedService* CreateNotificationScheduleService(
std::unique_ptr<NotificationSchedulerClientRegistrar> client_registrar,
std::unique_ptr<NotificationBackgroundTaskScheduler>
background_task_scheduler,
leveldb_proto::ProtoDatabaseProvider* db_provider,
......
......@@ -11,19 +11,6 @@
namespace notifications {
// Categorizes type of notification buttons. Different type of button clicks
// may result in change of notification shown frequency.
enum class ActionButtonType {
// The action button is not categorized.
kUnknownAction = 0,
// Helpful button indicates the user likes to interact with the notification.
kHelpful = 1,
// Unhelpful button indicates dislike of the notification.
kUnhelpful = 2,
};
// An interface to plumb user actions events to notification scheduling system.
// Each event needs to provide an unique id of the notification shown.
class UserActionHandler {
......
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