Skip to content

Commit

Permalink
Merge pull request #19222 from brave/issues/31524
Browse files Browse the repository at this point in the history
Queue ad events until ads library is initialized.
  • Loading branch information
aseren authored Jul 13, 2023
2 parents 12a5229 + 5935897 commit d51e294
Show file tree
Hide file tree
Showing 18 changed files with 535 additions and 21 deletions.
2 changes: 1 addition & 1 deletion components/brave_ads/core/ads_client.h
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ class ADS_EXPORT AdsClient {
virtual void RemoveObserver(AdsClientNotifierObserver* observer) = 0;

// Called to bind pending ads client observers.
virtual void BindPendingObservers() = 0;
virtual void NotifyPendingObservers() = 0;

// Returns |true| if there is an available network connection.
virtual bool IsNetworkConnectionAvailable() const = 0;
Expand Down
22 changes: 22 additions & 0 deletions components/brave_ads/core/ads_client_notifier.h
Original file line number Diff line number Diff line change
Expand Up @@ -7,16 +7,20 @@
#define BRAVE_COMPONENTS_BRAVE_ADS_CORE_ADS_CLIENT_NOTIFIER_H_

#include <cstdint>
#include <memory>
#include <string>
#include <vector>

#include "base/memory/weak_ptr.h"
#include "base/observer_list.h"
#include "brave/components/brave_ads/core/ads_client_notifier_observer.h"

class GURL;

namespace brave_ads {

class AdsClientNotifierQueue;

class AdsClientNotifier {
public:
AdsClientNotifier();
Expand All @@ -32,6 +36,9 @@ class AdsClientNotifier {
void AddObserver(AdsClientNotifierObserver* observer);
void RemoveObserver(AdsClientNotifierObserver* observer);

// Invoked to fire all pending observer events.
void NotifyPendingObservers();

// Invoked when ads did initialize.
void NotifyDidInitializeAds() const;

Expand Down Expand Up @@ -125,8 +132,23 @@ class AdsClientNotifier {
// Invoked when the user solves an adaptive captch.
void NotifyDidSolveAdaptiveCaptcha() const;

void set_should_queue_notifications_for_testing(
bool should_queue_notifications) {
should_queue_notifications_ = should_queue_notifications;
}

private:
base::ObserverList<AdsClientNotifierObserver> observers_;

std::unique_ptr<AdsClientNotifierQueue> pending_notifier_queue_;

#if BUILDFLAG(IS_IOS)
bool should_queue_notifications_ = true;
#else
bool should_queue_notifications_ = false;
#endif // BUILDFLAG(IS_IOS)

base::WeakPtrFactory<AdsClientNotifier> weak_factory_{this};
};

} // namespace brave_ads
Expand Down
2 changes: 2 additions & 0 deletions components/brave_ads/core/internal/BUILD.gn
Original file line number Diff line number Diff line change
Expand Up @@ -507,6 +507,8 @@ source_set("internal") {
"ads_client_helper.h",
"ads_client_notifier.cc",
"ads_client_notifier_observer.cc",
"ads_client_notifier_queue.cc",
"ads_client_notifier_queue.h",
"ads_impl.cc",
"ads_impl.h",
"ads_util.cc",
Expand Down
2 changes: 1 addition & 1 deletion components/brave_ads/core/internal/ads_client_mock.h
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ class AdsClientMock : public AdsClient {

MOCK_METHOD1(AddObserver, void(AdsClientNotifierObserver*));
MOCK_METHOD1(RemoveObserver, void(AdsClientNotifierObserver*));
MOCK_METHOD0(BindPendingObservers, void());
MOCK_METHOD0(NotifyPendingObservers, void());

MOCK_CONST_METHOD0(IsNetworkConnectionAvailable, bool());

Expand Down
145 changes: 144 additions & 1 deletion components/brave_ads/core/internal/ads_client_notifier.cc
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,16 @@

#include "brave/components/brave_ads/core/ads_client_notifier.h"

#include <memory>

#include "base/functional/bind.h"
#include "brave/components/brave_ads/core/internal/ads_client_notifier_queue.h"
#include "url/gurl.h"

namespace brave_ads {

AdsClientNotifier::AdsClientNotifier() = default;
AdsClientNotifier::AdsClientNotifier()
: pending_notifier_queue_(std::make_unique<AdsClientNotifierQueue>()) {}

AdsClientNotifier::~AdsClientNotifier() = default;

Expand All @@ -23,7 +28,19 @@ void AdsClientNotifier::RemoveObserver(AdsClientNotifierObserver* observer) {
observers_.RemoveObserver(observer);
}

void AdsClientNotifier::NotifyPendingObservers() {
should_queue_notifications_ = false;
pending_notifier_queue_->Process();
}

void AdsClientNotifier::NotifyDidInitializeAds() const {
if (should_queue_notifications_) {
pending_notifier_queue_->Add(
base::BindOnce(&AdsClientNotifier::NotifyDidInitializeAds,
weak_factory_.GetWeakPtr()));
return;
}

for (auto& observer : observers_) {
observer.OnNotifyDidInitializeAds();
}
Expand All @@ -32,18 +49,39 @@ void AdsClientNotifier::NotifyDidInitializeAds() const {
void AdsClientNotifier::NotifyRewardsWalletDidUpdate(
const std::string& payment_id,
const std::string& recovery_seed) const {
if (should_queue_notifications_) {
pending_notifier_queue_->Add(
base::BindOnce(&AdsClientNotifier::NotifyRewardsWalletDidUpdate,
weak_factory_.GetWeakPtr(), payment_id, recovery_seed));
return;
}

for (auto& observer : observers_) {
observer.OnNotifyRewardsWalletDidUpdate(payment_id, recovery_seed);
}
}

void AdsClientNotifier::NotifyLocaleDidChange(const std::string& locale) const {
if (should_queue_notifications_) {
pending_notifier_queue_->Add(
base::BindOnce(&AdsClientNotifier::NotifyLocaleDidChange,
weak_factory_.GetWeakPtr(), locale));
return;
}

for (auto& observer : observers_) {
observer.OnNotifyLocaleDidChange(locale);
}
}

void AdsClientNotifier::NotifyPrefDidChange(const std::string& path) const {
if (should_queue_notifications_) {
pending_notifier_queue_->Add(
base::BindOnce(&AdsClientNotifier::NotifyPrefDidChange,
weak_factory_.GetWeakPtr(), path));
return;
}

for (auto& observer : observers_) {
observer.OnNotifyPrefDidChange(path);
}
Expand All @@ -52,6 +90,13 @@ void AdsClientNotifier::NotifyPrefDidChange(const std::string& path) const {
void AdsClientNotifier::NotifyDidUpdateResourceComponent(
const std::string& manifest_version,
const std::string& id) const {
if (should_queue_notifications_) {
pending_notifier_queue_->Add(
base::BindOnce(&AdsClientNotifier::NotifyDidUpdateResourceComponent,
weak_factory_.GetWeakPtr(), manifest_version, id));
return;
}

for (auto& observer : observers_) {
observer.OnNotifyDidUpdateResourceComponent(manifest_version, id);
}
Expand All @@ -61,6 +106,13 @@ void AdsClientNotifier::NotifyTabTextContentDidChange(
const int32_t tab_id,
const std::vector<GURL>& redirect_chain,
const std::string& text) const {
if (should_queue_notifications_) {
pending_notifier_queue_->Add(base::BindOnce(
&AdsClientNotifier::NotifyTabTextContentDidChange,
weak_factory_.GetWeakPtr(), tab_id, redirect_chain, text));
return;
}

for (auto& observer : observers_) {
observer.OnNotifyTabTextContentDidChange(tab_id, redirect_chain, text);
}
Expand All @@ -70,20 +122,41 @@ void AdsClientNotifier::NotifyTabHtmlContentDidChange(
const int32_t tab_id,
const std::vector<GURL>& redirect_chain,
const std::string& html) const {
if (should_queue_notifications_) {
pending_notifier_queue_->Add(base::BindOnce(
&AdsClientNotifier::NotifyTabHtmlContentDidChange,
weak_factory_.GetWeakPtr(), tab_id, redirect_chain, html));
return;
}

for (auto& observer : observers_) {
observer.OnNotifyTabHtmlContentDidChange(tab_id, redirect_chain, html);
}
}

void AdsClientNotifier::NotifyTabDidStartPlayingMedia(
const int32_t tab_id) const {
if (should_queue_notifications_) {
pending_notifier_queue_->Add(
base::BindOnce(&AdsClientNotifier::NotifyTabDidStartPlayingMedia,
weak_factory_.GetWeakPtr(), tab_id));
return;
}

for (auto& observer : observers_) {
observer.OnNotifyTabDidStartPlayingMedia(tab_id);
}
}

void AdsClientNotifier::NotifyTabDidStopPlayingMedia(
const int32_t tab_id) const {
if (should_queue_notifications_) {
pending_notifier_queue_->Add(
base::BindOnce(&AdsClientNotifier::NotifyTabDidStopPlayingMedia,
weak_factory_.GetWeakPtr(), tab_id));
return;
}

for (auto& observer : observers_) {
observer.OnNotifyTabDidStopPlayingMedia(tab_id);
}
Expand All @@ -93,25 +166,53 @@ void AdsClientNotifier::NotifyTabDidChange(
const int32_t tab_id,
const std::vector<GURL>& redirect_chain,
const bool is_visible) const {
if (should_queue_notifications_) {
pending_notifier_queue_->Add(base::BindOnce(
&AdsClientNotifier::NotifyTabDidChange, weak_factory_.GetWeakPtr(),
tab_id, redirect_chain, is_visible));
return;
}

for (auto& observer : observers_) {
observer.OnNotifyTabDidChange(tab_id, redirect_chain, is_visible);
}
}

void AdsClientNotifier::NotifyDidCloseTab(const int32_t tab_id) const {
if (should_queue_notifications_) {
pending_notifier_queue_->Add(
base::BindOnce(&AdsClientNotifier::NotifyDidCloseTab,
weak_factory_.GetWeakPtr(), tab_id));
return;
}

for (auto& observer : observers_) {
observer.OnNotifyDidCloseTab(tab_id);
}
}

void AdsClientNotifier::NotifyUserGestureEventTriggered(
const int32_t page_transition_type) const {
if (should_queue_notifications_) {
pending_notifier_queue_->Add(
base::BindOnce(&AdsClientNotifier::NotifyUserGestureEventTriggered,
weak_factory_.GetWeakPtr(), page_transition_type));
return;
}

for (auto& observer : observers_) {
observer.OnNotifyUserGestureEventTriggered(page_transition_type);
}
}

void AdsClientNotifier::NotifyUserDidBecomeIdle() const {
if (should_queue_notifications_) {
pending_notifier_queue_->Add(
base::BindOnce(&AdsClientNotifier::NotifyUserDidBecomeIdle,
weak_factory_.GetWeakPtr()));
return;
}

for (auto& observer : observers_) {
observer.OnNotifyUserDidBecomeIdle();
}
Expand All @@ -120,36 +221,78 @@ void AdsClientNotifier::NotifyUserDidBecomeIdle() const {
void AdsClientNotifier::NotifyUserDidBecomeActive(
const base::TimeDelta idle_time,
const bool screen_was_locked) const {
if (should_queue_notifications_) {
pending_notifier_queue_->Add(base::BindOnce(
&AdsClientNotifier::NotifyUserDidBecomeActive,
weak_factory_.GetWeakPtr(), idle_time, screen_was_locked));
return;
}

for (auto& observer : observers_) {
observer.OnNotifyUserDidBecomeActive(idle_time, screen_was_locked);
}
}

void AdsClientNotifier::NotifyBrowserDidEnterForeground() const {
if (should_queue_notifications_) {
pending_notifier_queue_->Add(
base::BindOnce(&AdsClientNotifier::NotifyBrowserDidEnterForeground,
weak_factory_.GetWeakPtr()));
return;
}

for (auto& observer : observers_) {
observer.OnNotifyBrowserDidEnterForeground();
}
}

void AdsClientNotifier::NotifyBrowserDidEnterBackground() const {
if (should_queue_notifications_) {
pending_notifier_queue_->Add(
base::BindOnce(&AdsClientNotifier::NotifyBrowserDidEnterBackground,
weak_factory_.GetWeakPtr()));
return;
}

for (auto& observer : observers_) {
observer.OnNotifyBrowserDidEnterBackground();
}
}

void AdsClientNotifier::NotifyBrowserDidBecomeActive() const {
if (should_queue_notifications_) {
pending_notifier_queue_->Add(
base::BindOnce(&AdsClientNotifier::NotifyBrowserDidBecomeActive,
weak_factory_.GetWeakPtr()));
return;
}

for (auto& observer : observers_) {
observer.OnNotifyBrowserDidBecomeActive();
}
}

void AdsClientNotifier::NotifyBrowserDidResignActive() const {
if (should_queue_notifications_) {
pending_notifier_queue_->Add(
base::BindOnce(&AdsClientNotifier::NotifyBrowserDidResignActive,
weak_factory_.GetWeakPtr()));
return;
}

for (auto& observer : observers_) {
observer.OnNotifyBrowserDidResignActive();
}
}

void AdsClientNotifier::NotifyDidSolveAdaptiveCaptcha() const {
if (should_queue_notifications_) {
pending_notifier_queue_->Add(
base::BindOnce(&AdsClientNotifier::NotifyDidSolveAdaptiveCaptcha,
weak_factory_.GetWeakPtr()));
return;
}

for (auto& observer : observers_) {
observer.OnNotifyDidSolveAdaptiveCaptcha();
}
Expand Down
27 changes: 27 additions & 0 deletions components/brave_ads/core/internal/ads_client_notifier_queue.cc
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
/* Copyright (c) 2023 The Brave Authors. All rights reserved.
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
* You can obtain one at https://mozilla.org/MPL/2.0/. */

#include "brave/components/brave_ads/core/internal/ads_client_notifier_queue.h"

#include <utility>

namespace brave_ads {

AdsClientNotifierQueue::AdsClientNotifierQueue() = default;

AdsClientNotifierQueue::~AdsClientNotifierQueue() = default;

void AdsClientNotifierQueue::Add(base::OnceClosure notifier) {
queue_.push(std::move(notifier));
}

void AdsClientNotifierQueue::Process() {
while (!queue_.empty()) {
std::move(queue_.front()).Run();
queue_.pop();
}
}

} // namespace brave_ads
Loading

0 comments on commit d51e294

Please sign in to comment.