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") { ...@@ -26,6 +26,9 @@ source_set("public") {
"notification_params.cc", "notification_params.cc",
"notification_params.h", "notification_params.h",
"notification_schedule_service.h", "notification_schedule_service.h",
"notification_scheduler_client.h",
"notification_scheduler_client_registrar.cc",
"notification_scheduler_client_registrar.h",
"notification_scheduler_types.h", "notification_scheduler_types.h",
"schedule_params.cc", "schedule_params.cc",
"schedule_params.h", "schedule_params.h",
...@@ -35,6 +38,7 @@ source_set("public") { ...@@ -35,6 +38,7 @@ source_set("public") {
deps = [ deps = [
"//base", "//base",
"//components/keyed_service/core", "//components/keyed_service/core",
"//skia",
] ]
} }
...@@ -112,6 +116,7 @@ source_set("lib") { ...@@ -112,6 +116,7 @@ source_set("lib") {
"//chrome/browser/notifications/proto", "//chrome/browser/notifications/proto",
"//components/keyed_service/core", "//components/keyed_service/core",
"//components/leveldb_proto", "//components/leveldb_proto",
"//skia",
] ]
} }
......
...@@ -9,6 +9,7 @@ ...@@ -9,6 +9,7 @@
#include "chrome/browser/notifications/scheduler/notification_background_task_scheduler_impl.h" #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_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/notification_scheduler_context.h"
#include "chrome/browser/notifications/scheduler/schedule_service_factory_helper.h" #include "chrome/browser/notifications/scheduler/schedule_service_factory_helper.h"
#include "chrome/browser/profiles/incognito_helpers.h" #include "chrome/browser/profiles/incognito_helpers.h"
...@@ -17,6 +18,18 @@ ...@@ -17,6 +18,18 @@
#include "components/keyed_service/content/browser_context_dependency_manager.h" #include "components/keyed_service/content/browser_context_dependency_manager.h"
#include "components/leveldb_proto/content/proto_database_provider_factory.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 // static
NotificationScheduleServiceFactory* NotificationScheduleServiceFactory*
NotificationScheduleServiceFactory::GetInstance() { NotificationScheduleServiceFactory::GetInstance() {
...@@ -47,12 +60,14 @@ KeyedService* NotificationScheduleServiceFactory::BuildServiceInstanceFor( ...@@ -47,12 +60,14 @@ KeyedService* NotificationScheduleServiceFactory::BuildServiceInstanceFor(
auto* profile = Profile::FromBrowserContext(context); auto* profile = Profile::FromBrowserContext(context);
base::FilePath storage_dir = base::FilePath storage_dir =
profile->GetPath().Append(chrome::kNotificationSchedulerStorageDirname); profile->GetPath().Append(chrome::kNotificationSchedulerStorageDirname);
auto client_registrar = RegisterClients();
auto background_task_scheduler = auto background_task_scheduler =
std::make_unique<NotificationBackgroundTaskSchedulerImpl>(); std::make_unique<NotificationBackgroundTaskSchedulerImpl>();
auto* db_provider = leveldb_proto::ProtoDatabaseProviderFactory::GetForKey( auto* db_provider = leveldb_proto::ProtoDatabaseProviderFactory::GetForKey(
profile->GetProfileKey()); profile->GetProfileKey());
return notifications::CreateNotificationScheduleService( 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* content::BrowserContext*
......
...@@ -5,6 +5,7 @@ ...@@ -5,6 +5,7 @@
#include "chrome/browser/notifications/scheduler/notification_scheduler.h" #include "chrome/browser/notifications/scheduler/notification_scheduler.h"
#include <utility> #include <utility>
#include <vector>
#include "base/bind.h" #include "base/bind.h"
#include "base/logging.h" #include "base/logging.h"
...@@ -17,6 +18,8 @@ ...@@ -17,6 +18,8 @@
#include "chrome/browser/notifications/scheduler/notification_background_task_scheduler.h" #include "chrome/browser/notifications/scheduler/notification_background_task_scheduler.h"
#include "chrome/browser/notifications/scheduler/notification_entry.h" #include "chrome/browser/notifications/scheduler/notification_entry.h"
#include "chrome/browser/notifications/scheduler/notification_params.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/notification_scheduler_context.h"
#include "chrome/browser/notifications/scheduler/scheduled_notification_manager.h" #include "chrome/browser/notifications/scheduler/scheduled_notification_manager.h"
...@@ -160,8 +163,11 @@ class NotificationSchedulerImpl ...@@ -160,8 +163,11 @@ class NotificationSchedulerImpl
for (const auto& client_state : client_states) { for (const auto& client_state : client_states) {
client_state_ptrs.emplace(client_state.first, client_state.second.get()); 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_->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), task_start_time, std::move(notifications), std::move(client_state_ptrs),
&results); &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 @@ ...@@ -10,19 +10,22 @@
#include "chrome/browser/notifications/scheduler/icon_store.h" #include "chrome/browser/notifications/scheduler/icon_store.h"
#include "chrome/browser/notifications/scheduler/impression_history_tracker.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_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/scheduled_notification_manager.h"
#include "chrome/browser/notifications/scheduler/scheduler_config.h" #include "chrome/browser/notifications/scheduler/scheduler_config.h"
namespace notifications { namespace notifications {
NotificationSchedulerContext::NotificationSchedulerContext( NotificationSchedulerContext::NotificationSchedulerContext(
std::unique_ptr<NotificationSchedulerClientRegistrar> client_registrar,
std::unique_ptr<NotificationBackgroundTaskScheduler> scheduler, std::unique_ptr<NotificationBackgroundTaskScheduler> scheduler,
std::unique_ptr<IconStore> icon_store, std::unique_ptr<IconStore> icon_store,
std::unique_ptr<ImpressionHistoryTracker> impression_tracker, std::unique_ptr<ImpressionHistoryTracker> impression_tracker,
std::unique_ptr<ScheduledNotificationManager> notification_manager, std::unique_ptr<ScheduledNotificationManager> notification_manager,
std::unique_ptr<DisplayDecider> display_decider, std::unique_ptr<DisplayDecider> display_decider,
std::unique_ptr<SchedulerConfig> config) 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)), impression_tracker_(std::move(impression_tracker)),
notification_manager_(std::move(notification_manager)), notification_manager_(std::move(notification_manager)),
display_decider_(std::move(display_decider)), display_decider_(std::move(display_decider)),
......
...@@ -17,6 +17,7 @@ class DisplayDecider; ...@@ -17,6 +17,7 @@ class DisplayDecider;
class IconStore; class IconStore;
class ImpressionHistoryTracker; class ImpressionHistoryTracker;
class NotificationBackgroundTaskScheduler; class NotificationBackgroundTaskScheduler;
class NotificationSchedulerClientRegistrar;
class ScheduledNotificationManager; class ScheduledNotificationManager;
struct SchedulerConfig; struct SchedulerConfig;
...@@ -25,6 +26,7 @@ struct SchedulerConfig; ...@@ -25,6 +26,7 @@ struct SchedulerConfig;
class NotificationSchedulerContext { class NotificationSchedulerContext {
public: public:
NotificationSchedulerContext( NotificationSchedulerContext(
std::unique_ptr<NotificationSchedulerClientRegistrar> client_registrar,
std::unique_ptr<NotificationBackgroundTaskScheduler> scheduler, std::unique_ptr<NotificationBackgroundTaskScheduler> scheduler,
std::unique_ptr<IconStore> icon_store, std::unique_ptr<IconStore> icon_store,
std::unique_ptr<ImpressionHistoryTracker> impression_tracker, std::unique_ptr<ImpressionHistoryTracker> impression_tracker,
...@@ -33,7 +35,9 @@ class NotificationSchedulerContext { ...@@ -33,7 +35,9 @@ class NotificationSchedulerContext {
std::unique_ptr<SchedulerConfig> config); std::unique_ptr<SchedulerConfig> config);
~NotificationSchedulerContext(); ~NotificationSchedulerContext();
const std::vector<SchedulerClientType>& clients() const { return clients_; } NotificationSchedulerClientRegistrar* client_registrar() {
return client_registrar_.get();
}
NotificationBackgroundTaskScheduler* background_task_scheduler() { NotificationBackgroundTaskScheduler* background_task_scheduler() {
return background_task_scheduler_.get(); return background_task_scheduler_.get();
...@@ -54,9 +58,8 @@ class NotificationSchedulerContext { ...@@ -54,9 +58,8 @@ class NotificationSchedulerContext {
const SchedulerConfig* config() const { return config_.get(); } const SchedulerConfig* config() const { return config_.get(); }
private: private:
// List of clients using the notification scheduler system. // Holds a list of clients using the notification scheduler system.
// TODO(xingliu): Pass in the registered the clients. std::unique_ptr<NotificationSchedulerClientRegistrar> client_registrar_;
std::vector<SchedulerClientType> clients_;
// Used to schedule background task in OS level. // Used to schedule background task in OS level.
std::unique_ptr<NotificationBackgroundTaskScheduler> std::unique_ptr<NotificationBackgroundTaskScheduler>
......
...@@ -52,7 +52,8 @@ enum class UserFeedback { ...@@ -52,7 +52,8 @@ enum class UserFeedback {
kMaxValue = kIgnore 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 { enum class ImpressionResult {
// Invalid user impression. // Invalid user impression.
kInvalid = 0, kInvalid = 0,
...@@ -65,6 +66,19 @@ enum class ImpressionResult { ...@@ -65,6 +66,19 @@ enum class ImpressionResult {
kMaxValue = kNeutral 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 } // namespace notifications
#endif // CHROME_BROWSER_NOTIFICATIONS_SCHEDULER_NOTIFICATION_SCHEDULER_TYPES_H_ #endif // CHROME_BROWSER_NOTIFICATIONS_SCHEDULER_NOTIFICATION_SCHEDULER_TYPES_H_
...@@ -15,6 +15,7 @@ ...@@ -15,6 +15,7 @@
#include "chrome/browser/notifications/scheduler/init_aware_scheduler.h" #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_background_task_scheduler.h"
#include "chrome/browser/notifications/scheduler/notification_schedule_service_impl.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_scheduler_context.h"
#include "chrome/browser/notifications/scheduler/notification_store.h" #include "chrome/browser/notifications/scheduler/notification_store.h"
#include "chrome/browser/notifications/scheduler/scheduled_notification_manager.h" #include "chrome/browser/notifications/scheduler/scheduled_notification_manager.h"
...@@ -32,6 +33,7 @@ const base::FilePath::CharType kNotificationDBName[] = ...@@ -32,6 +33,7 @@ const base::FilePath::CharType kNotificationDBName[] =
} // namespace } // namespace
KeyedService* CreateNotificationScheduleService( KeyedService* CreateNotificationScheduleService(
std::unique_ptr<NotificationSchedulerClientRegistrar> client_registrar,
std::unique_ptr<NotificationBackgroundTaskScheduler> std::unique_ptr<NotificationBackgroundTaskScheduler>
background_task_scheduler, background_task_scheduler,
leveldb_proto::ProtoDatabaseProvider* db_provider, leveldb_proto::ProtoDatabaseProvider* db_provider,
...@@ -71,9 +73,10 @@ KeyedService* CreateNotificationScheduleService( ...@@ -71,9 +73,10 @@ KeyedService* CreateNotificationScheduleService(
notification_manager->Create(std::move(notification_store)); notification_manager->Create(std::move(notification_store));
auto context = std::make_unique<NotificationSchedulerContext>( auto context = std::make_unique<NotificationSchedulerContext>(
std::move(background_task_scheduler), std::move(icon_store), std::move(client_registrar), std::move(background_task_scheduler),
std::move(impression_tracker), std::move(notification_manager), std::move(icon_store), std::move(impression_tracker),
DisplayDecider::Create(), std::move(config)); std::move(notification_manager), DisplayDecider::Create(),
std::move(config));
auto scheduler = NotificationScheduler::Create(std::move(context)); auto scheduler = NotificationScheduler::Create(std::move(context));
auto init_aware_scheduler = auto init_aware_scheduler =
......
...@@ -18,11 +18,13 @@ class ProtoDatabaseProvider; ...@@ -18,11 +18,13 @@ class ProtoDatabaseProvider;
namespace notifications { namespace notifications {
class NotificationBackgroundTaskScheduler; class NotificationBackgroundTaskScheduler;
class NotificationSchedulerClientRegistrar;
// Creates the notification schedule service with all the embedder level // Creates the notification schedule service with all the embedder level
// dependencies. This layer is mainly to forbid the embedder to depend on // dependencies. This layer is mainly to forbid the embedder to depend on
// notification scheduler internal code. // notification scheduler internal code.
KeyedService* CreateNotificationScheduleService( KeyedService* CreateNotificationScheduleService(
std::unique_ptr<NotificationSchedulerClientRegistrar> client_registrar,
std::unique_ptr<NotificationBackgroundTaskScheduler> std::unique_ptr<NotificationBackgroundTaskScheduler>
background_task_scheduler, background_task_scheduler,
leveldb_proto::ProtoDatabaseProvider* db_provider, leveldb_proto::ProtoDatabaseProvider* db_provider,
......
...@@ -11,19 +11,6 @@ ...@@ -11,19 +11,6 @@
namespace notifications { 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. // An interface to plumb user actions events to notification scheduling system.
// Each event needs to provide an unique id of the notification shown. // Each event needs to provide an unique id of the notification shown.
class UserActionHandler { 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