1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172
|
// Copyright 2022 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef COMPONENTS_COMMERCE_CORE_PRICE_TRACKING_UTILS_H_
#define COMPONENTS_COMMERCE_CORE_PRICE_TRACKING_UTILS_H_
#include <optional>
#include <vector>
#include "base/functional/callback.h"
#include "base/memory/raw_ptr.h"
#include "base/scoped_observation.h"
#include "components/bookmarks/browser/base_bookmark_model_observer.h"
#include "components/bookmarks/browser/bookmark_model.h"
#include "components/commerce/core/commerce_types.h"
#include "components/power_bookmarks/core/proto/power_bookmark_meta.pb.h"
class PrefService;
namespace bookmarks {
class BookmarkModel;
class BookmarkNode;
} // namespace bookmarks
namespace power_bookmarks {
class ShoppingSpecifics;
} // namespace power_bookmarks
namespace commerce {
struct CommerceSubscription;
struct ProductInfo;
class ShoppingService;
// Return whether a bookmark is price tracked. The result is passed to
// |callback|.
void IsBookmarkPriceTracked(ShoppingService* service,
bookmarks::BookmarkModel* model,
const bookmarks::BookmarkNode* node,
base::OnceCallback<void(bool)> callback);
// Return whether the |node| is a product bookmark.
bool IsProductBookmark(bookmarks::BookmarkModel* model,
const bookmarks::BookmarkNode* node);
// Return the last timestamp when the product is successfully tracked or
// untracked by the user.
std::optional<int64_t> GetBookmarkLastSubscriptionChangeTime(
bookmarks::BookmarkModel* model,
const bookmarks::BookmarkNode* node);
// Set the price tracking state for a particular cluster ID. This function
// assumes that a bookmark with the specified cluster ID already exists and
// will search for that bookmark (or the first instance of it). The logic
// performed after that point will be the same as
// SetPriceTrackingStateForBookmark.
void SetPriceTrackingStateForClusterId(ShoppingService* service,
bookmarks::BookmarkModel* model,
const uint64_t cluster_id,
bool enabled,
base::OnceCallback<void(bool)> callback);
// Set the state of price tracking for all bookmarks with the cluster ID of the
// provided bookmark. A subscription update will attempted on the backend and,
// if successful, all bookmarks with the same cluster ID will be updated.
// |callback| will be called with a bool representing whether the operation was
// successful iff all of |service|, |model|, and |node| are non-null and the
// bookmark has been determined to be a product. ProductInfo can be passed
// in optionally here and used as a fallback, in the event that ShoppingService
// is unaware of ProductInfo.
void SetPriceTrackingStateForBookmark(
ShoppingService* service,
bookmarks::BookmarkModel* model,
const bookmarks::BookmarkNode* node,
bool enabled,
base::OnceCallback<void(bool)> callback,
bool was_bookmark_created_by_price_tracking = false,
std::optional<ProductInfo> product_info = std::nullopt);
// Get all bookmarks with the specified product cluster ID. If |max_count| is
// specified, this function will return that number of bookmarks at most,
// otherwise all bookmarks with the specified cluster ID will be returned.
std::vector<const bookmarks::BookmarkNode*> GetBookmarksWithClusterId(
bookmarks::BookmarkModel* model,
uint64_t cluster_id,
size_t max_count = 0);
// Gets all bookmarks that are price tracked. This method may make a call to the
// subscriptions backend if the information is stale. The list of price tracked
// bookmarks is provided as a param to the callback passed to this function.
// Ownership of the vector of bookmark nodes is transferred to the caller, but
// the individual bookmarks that the pointers reference are not -- those exist
// only as long as the BookmarkModel does (which is bound to the browser
// context).
void GetAllPriceTrackedBookmarks(
ShoppingService* shopping_service,
bookmarks::BookmarkModel* bookmark_model,
base::OnceCallback<void(std::vector<const bookmarks::BookmarkNode*>)>
callback);
// Get all shopping bookmarks. The returned vector of BookmarkNodes is owned by
// the caller, but the nodes pointed to are not -- those live for as long as
// the BookmarkModel (|model|) is alive which has the same lifetime as the
// current BrowserContext.
std::vector<const bookmarks::BookmarkNode*> GetAllShoppingBookmarks(
bookmarks::BookmarkModel* model);
// Populate or update the provided |out_meta| with information from |info|. The
// returned boolean indicated whether any information actually changed.
bool PopulateOrUpdateBookmarkMetaIfNeeded(
power_bookmarks::PowerBookmarkMeta* out_meta,
const ProductInfo& info);
// Attempts to enable price email notifications for users. This will only set
// the setting to true if it is the first time being called, after that this is
// a noop.
void MaybeEnableEmailNotifications(PrefService* pref_service);
// Gets the user preference for price drop notifications. If not set, the
// default value will be returned.
bool GetEmailNotificationPrefValue(PrefService* pref_service);
// Gets whether the price drop email notification preference has been explicitly
// set by the user or is still in the default state.
bool IsEmailNotificationPrefSetByUser(PrefService* pref_service);
// Builds a user-managed price tracking subscription object for the provided
// cluster ID. This does not change the state of the subscription, it only
// creates the object representing the subscription.
CommerceSubscription BuildUserSubscriptionForClusterId(uint64_t cluster_id);
// Returns whether price tracking can be initiated given either a ProductInfo
// or a ShoppingSpecifics object.
bool CanTrackPrice(const ProductInfo& info);
bool CanTrackPrice(const std::optional<ProductInfo>& info);
bool CanTrackPrice(const power_bookmarks::ShoppingSpecifics& specifics);
// If `url` is bookmarked, returns the name of the parent folder; otherwise
// returns an empty string.
std::optional<std::u16string> GetBookmarkParentName(
bookmarks::BookmarkModel* model,
const GURL& url);
// Gets the explicit "shopping collection" bookmark folder. There can only be
// one shopping collection per profile.
const bookmarks::BookmarkNode* GetShoppingCollectionBookmarkFolder(
bookmarks::BookmarkModel* model,
bool create_if_needed = false);
// Returns whether the provided node is the shopping collection folder.
bool IsShoppingCollectionBookmarkFolder(const bookmarks::BookmarkNode* node);
// Gets the product cluster ID for the bookmark represented by the provided URL.
// If there is no bookmark or the bookmark doesn't have a cluster ID,
// std::nullopt is returned.
std::optional<uint64_t> GetProductClusterIdFromBookmark(
const GURL& url,
bookmarks::BookmarkModel* model);
// Removes any subscriptions the user might have that are not tied to at least
// one bookmark. The count of the number of dangling subscriptions will be
// returned as part of the optionally provided callback.
void RemoveDanglingSubscriptions(
ShoppingService* shopping_service,
bookmarks::BookmarkModel* bookmark_model,
base::OnceCallback<void(size_t)> completed_callback =
base::DoNothingAs<void(size_t)>());
} // namespace commerce
#endif // COMPONENTS_COMMERCE_CORE_PRICE_TRACKING_UTILS_H_
|