File: cluster_manager.h

package info (click to toggle)
chromium 139.0.7258.127-1
  • links: PTS, VCS
  • area: main
  • in suites:
  • size: 6,122,068 kB
  • sloc: cpp: 35,100,771; ansic: 7,163,530; javascript: 4,103,002; python: 1,436,920; asm: 946,517; xml: 746,709; pascal: 187,653; perl: 88,691; sh: 88,436; objc: 79,953; sql: 51,488; cs: 44,583; fortran: 24,137; makefile: 22,147; tcl: 15,277; php: 13,980; yacc: 8,984; ruby: 7,485; awk: 3,720; lisp: 3,096; lex: 1,327; ada: 727; jsp: 228; sed: 36
file content (193 lines) | stat: -rw-r--r-- 7,785 bytes parent folder | download | duplicates (6)
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
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
// Copyright 2024 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_COMPARE_CLUSTER_MANAGER_H_
#define COMPONENTS_COMMERCE_CORE_COMPARE_CLUSTER_MANAGER_H_

#include <map>
#include <memory>
#include <set>
#include <vector>

#include "base/memory/weak_ptr.h"
#include "base/observer_list.h"
#include "base/observer_list_types.h"
#include "base/scoped_observation.h"
#include "base/uuid.h"
#include "components/commerce/core/commerce_types.h"
#include "components/commerce/core/product_specifications/product_specifications_set.h"
#include "url/gurl.h"

namespace commerce {
class ClusterServerProxy;
class ProductSpecificationsService;
struct CandidateProduct;
struct ProductGroup;

// Class for clustering product information.
class ClusterManager : public ProductSpecificationsSet::Observer {
 public:
  using GetProductInfoCallback =
      base::RepeatingCallback<void(const GURL&, ProductInfoCallback)>;
  using GetProductInfoBatchCallback =
      base::RepeatingCallback<void(const std::vector<GURL>& urls,
                                   ProductInfoBatchCallback)>;
  using GetOpenUrlInfosCallback =
      base::RepeatingCallback<const std::vector<UrlInfo>()>;
  using GetEntryPointInfoCallback =
      base::OnceCallback<void(std::optional<EntryPointInfo>)>;

  class Observer : public base::CheckedObserver {
   public:
    // Notifies that ClusterManager has finished clustering for a recent
    // navigation with `url`.
    virtual void OnClusterFinishedForNavigation(const GURL& url) {}
  };

  ClusterManager(ProductSpecificationsService* product_specification_service,
                 std::unique_ptr<ClusterServerProxy> cluster_server_proxy,
                 const GetProductInfoCallback& get_product_info_cb,
                 const GetProductInfoBatchCallback& get_product_info_batch_cb,
                 const GetOpenUrlInfosCallback& get_open_url_infos_cb);
  ~ClusterManager() override;
  ClusterManager(const ClusterManager&) = delete;
  ClusterManager& operator=(const ClusterManager&) = delete;

  // ProductSpecificationsSet::Observe Implementation.
  void OnProductSpecificationsSetAdded(
      const ProductSpecificationsSet& product_specifications_set) override;
  void OnProductSpecificationsSetUpdate(
      const ProductSpecificationsSet& before,
      const ProductSpecificationsSet& product_specifications_set) override;
  void OnProductSpecificationsSetRemoved(
      const ProductSpecificationsSet& set) override;

  // A notification that a WebWrapper with `url` has been destroyed. This
  // signals that the web page backing the provided WebWrapper is about to be
  // destroyed. Typically corresponds to a user closing a tab.
  void WebWrapperDestroyed(const GURL& url);
  // A notification that a web wrapper with `url` finished a navigation in the
  // primary main frame.
  void DidNavigatePrimaryMainFrame(const GURL& url);
  // A notification that the user navigated away from `from_url`.
  void DidNavigateAway(const GURL& from_url);

  // Gets a product group that the given product can be clustered into. If
  // this candidate product is already in a product group, empty result
  // is returned.
  virtual std::optional<ProductGroup> GetProductGroupForCandidateProduct(
      const GURL& product_url);

  // Gets information to decide if entry point should show on navivation to
  // `url` and return it. The returned EntryPointInfo will include `url`
  // if it can be clustered into a group.
  virtual void GetEntryPointInfoForNavigation(
      const GURL& url,
      GetEntryPointInfoCallback callback);

  // Gets information to decide if entry point should show on selection and
  // return it. `old_url` is the URL of the tab before selection.
  // `new_url` is the URL of the tab after selection.
  virtual void GetEntryPointInfoForSelection(
      const GURL& old_url,
      const GURL& new_url,
      GetEntryPointInfoCallback callback);

  // Finds similar candidate products for a product group.
  std::vector<GURL> FindSimilarCandidateProductsForProductGroup(
      const base::Uuid& uuid);

  // Finds comparable products from an EntryPointInfo.
  virtual void GetComparableProducts(const EntryPointInfo& entry_point_info,
                                     GetEntryPointInfoCallback callback);

  // Registers an observer for cluster manager.
  void AddObserver(Observer* observer);

  // Removes an observer for cluster manager.
  void RemoveObserver(Observer* observer);

 private:
  friend class ClusterManagerTest;

  void OnGetAllProductSpecificationsSets(
      const std::vector<ProductSpecificationsSet> sets);

  // Called when information about a product is retrieved.
  void OnProductInfoRetrieved(
      const GURL& url,
      const std::optional<const ProductInfo>& product_info);

  // Called when category data for a list of URLs are retrieved.
  void OnAllCategoryDataRetrieved(
      const base::Uuid& uuid,
      const std::set<GURL>& urls,
      const std::vector<CategoryData>& category_data);

  // Adds a candidate product to `candidate_product_map_`.
  void AddCandidateProduct(
      const GURL& url,
      const std::optional<const ProductInfo>& product_info);

  // Removes a candidate product URL if it is not open in any tabs.
  void RemoveCandidateProductURLIfNotOpen(const GURL& url);

  // Finds similar candidate products for a candidate product. The returned
  // URLs doesn't include the `product_url`.
  std::set<GURL> FindSimilarCandidateProducts(const GURL& product_url);

  void OnGetComparableProducts(
      const EntryPointInfo& entry_point_info,
      GetEntryPointInfoCallback callback,
      const std::vector<uint64_t>& cluster_product_ids);

  void OnProductInfoFetchedForSimilarUrls(
      GetEntryPointInfoCallback callback,
      const std::map<GURL, std::optional<ProductInfo>> product_infos);

  // Check if product set is still eligible for clustering recommendations given
  // its uuid and last updated time. Please note that this method can be used
  // for both `ProductSpecificationSet` and `ProductGroup`.
  bool IsSetEligibleForClustering(const base::Uuid& uuid,
                                  const base::Time& update_time);

  // A ProductGroup might become ineligible for clustering because it hasn't
  // been updated for a long time. This method will be scheduled to run every
  // day after ClusterManager is constructed to remove the ineiligible
  // ProductGroups.
  //
  // Please note that this doesn't mean the underlying ProductSpecificationsSet
  // will be removed; only the ProductGroup is removed in ClusterManager so that
  // we'll stop making clustering recommendations for these ProductGroups.
  void RemoveIneligibleGroupsForClustering();

  std::unique_ptr<ClusterServerProxy> cluster_server_proxy_;

  // Callback to get product info.
  GetProductInfoCallback get_product_info_cb_;

  // Callback to get product info in batches.
  GetProductInfoBatchCallback get_product_info_batch_cb_;

  // Callback to get currently opened urls.
  GetOpenUrlInfosCallback get_open_url_infos_cb_;

  // A map storing info of existing product groups, keyed by product group ID.
  std::map<base::Uuid, std::unique_ptr<ProductGroup>> product_group_map_;

  // A map storing info of candidate products, keyed by product page URL.
  std::map<GURL, std::unique_ptr<CandidateProduct>> candidate_product_map_;

  base::ScopedObservation<ProductSpecificationsService,
                          ProductSpecificationsSet::Observer>
      obs_{this};

  base::ObserverList<Observer> observers_;

  base::WeakPtrFactory<ClusterManager> weak_ptr_factory_{this};
};

}  // namespace commerce

#endif  // COMPONENTS_COMMERCE_CORE_COMPARE_CLUSTER_MANAGER_H_