Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright 2015 The Chromium Authors. All rights reserved. | 1 // Copyright 2015 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #ifndef CHROME_BROWSER_ENGAGEMENT_SITE_ENGAGEMENT_SERVICE_H_ | 5 #ifndef CHROME_BROWSER_ENGAGEMENT_SITE_ENGAGEMENT_SERVICE_H_ |
| 6 #define CHROME_BROWSER_ENGAGEMENT_SITE_ENGAGEMENT_SERVICE_H_ | 6 #define CHROME_BROWSER_ENGAGEMENT_SITE_ENGAGEMENT_SERVICE_H_ |
| 7 | 7 |
| 8 #include <map> | 8 #include <map> |
| 9 #include <memory> | |
| 9 #include <set> | 10 #include <set> |
| 10 | 11 |
| 11 #include "base/gtest_prod_util.h" | 12 #include "base/gtest_prod_util.h" |
| 12 #include "base/macros.h" | 13 #include "base/macros.h" |
| 13 #include "base/memory/weak_ptr.h" | 14 #include "base/memory/weak_ptr.h" |
| 14 #include "base/time/time.h" | 15 #include "base/time/time.h" |
| 15 #include "chrome/browser/engagement/site_engagement_metrics.h" | 16 #include "chrome/browser/engagement/site_engagement_metrics.h" |
| 16 #include "components/history/core/browser/history_service_observer.h" | 17 #include "components/history/core/browser/history_service_observer.h" |
| 17 #include "components/keyed_service/core/keyed_service.h" | 18 #include "components/keyed_service/core/keyed_service.h" |
| 18 #include "ui/base/page_transition_types.h" | 19 #include "ui/base/page_transition_types.h" |
| 19 | 20 |
| 20 namespace base { | 21 namespace base { |
| 21 class DictionaryValue; | 22 class DictionaryValue; |
| 22 class Clock; | 23 class Clock; |
| 23 } | 24 } |
| 24 | 25 |
| 25 namespace history { | 26 namespace history { |
| 26 class HistoryService; | 27 class HistoryService; |
| 27 } | 28 } |
| 28 | 29 |
| 29 class GURL; | 30 class GURL; |
| 30 class Profile; | 31 class Profile; |
| 31 | 32 |
| 32 class SiteEngagementScore { | |
| 33 public: | |
| 34 // The parameters which can be varied via field trial. All "points" values | |
| 35 // should be appended to the end of the enum prior to MAX_VARIATION. | |
| 36 enum Variation { | |
| 37 // The maximum number of points that can be accrued in one day. | |
| 38 MAX_POINTS_PER_DAY = 0, | |
| 39 | |
| 40 // The period over which site engagement decays. | |
| 41 DECAY_PERIOD_IN_DAYS, | |
| 42 | |
| 43 // The number of points to decay per period. | |
| 44 DECAY_POINTS, | |
| 45 | |
| 46 // The number of points given for navigations. | |
| 47 NAVIGATION_POINTS, | |
| 48 | |
| 49 // The number of points given for user input. | |
| 50 USER_INPUT_POINTS, | |
| 51 | |
| 52 // The number of points given for media playing. Initially calibrated such | |
| 53 // that at least 30 minutes of foreground media would be required to allow a | |
| 54 // site to reach the daily engagement maximum. | |
| 55 VISIBLE_MEDIA_POINTS, | |
| 56 HIDDEN_MEDIA_POINTS, | |
| 57 | |
| 58 // The number of points added to engagement when a site is launched from | |
| 59 // homescreen or added as a bookmark app. This bonus will apply for ten days | |
| 60 // following a launch; each new launch resets the ten days. | |
| 61 WEB_APP_INSTALLED_POINTS, | |
| 62 | |
| 63 // The number of points given for the first engagement event of the day for | |
| 64 // each site. | |
| 65 FIRST_DAILY_ENGAGEMENT, | |
| 66 | |
| 67 // The number of points that the engagement service must accumulate to be | |
| 68 // considered 'useful'. | |
| 69 BOOTSTRAP_POINTS, | |
| 70 | |
| 71 // The boundaries between low/medium and medium/high engagement as returned | |
| 72 // by GetEngagementLevel(). | |
| 73 MEDIUM_ENGAGEMENT_BOUNDARY, | |
| 74 HIGH_ENGAGEMENT_BOUNDARY, | |
| 75 | |
| 76 MAX_VARIATION | |
| 77 }; | |
| 78 | |
| 79 // The maximum number of points that are allowed. | |
| 80 static const double kMaxPoints; | |
| 81 | |
| 82 static double GetMaxPointsPerDay(); | |
| 83 static double GetDecayPeriodInDays(); | |
| 84 static double GetDecayPoints(); | |
| 85 static double GetNavigationPoints(); | |
| 86 static double GetUserInputPoints(); | |
| 87 static double GetVisibleMediaPoints(); | |
| 88 static double GetHiddenMediaPoints(); | |
| 89 static double GetWebAppInstalledPoints(); | |
| 90 static double GetFirstDailyEngagementPoints(); | |
| 91 static double GetBootstrapPoints(); | |
| 92 static double GetMediumEngagementBoundary(); | |
| 93 static double GetHighEngagementBoundary(); | |
| 94 | |
| 95 // Update the default engagement settings via variations. | |
| 96 static void UpdateFromVariations(); | |
| 97 | |
| 98 // The SiteEngagementService does not take ownership of |clock|. It is the | |
| 99 // responsibility of the caller to make sure |clock| outlives this | |
| 100 // SiteEngagementScore. | |
| 101 SiteEngagementScore(base::Clock* clock, | |
| 102 const base::DictionaryValue& score_dict); | |
| 103 ~SiteEngagementScore(); | |
| 104 | |
| 105 double Score() const; | |
| 106 void AddPoints(double points); | |
| 107 | |
| 108 // Resets the score to |points| and resets the daily point limit. If | |
| 109 // |updated_time| is non-null, sets the last engagement time and last | |
| 110 // shortcut launch time (if it is non-null) to |updated_time|. Otherwise, last | |
| 111 // engagement time is set to the current time and last shortcut launch time is | |
| 112 // left unchanged. | |
| 113 // TODO(calamity): Ideally, all SiteEngagementScore methods should take a | |
| 114 // base::Time argument like this one does rather than each Score hold a | |
| 115 // pointer to a base::Clock. Then SiteEngagementScore doesn't need to worry | |
| 116 // about clock vending. See crbug.com/604305 | |
| 117 void Reset(double points, const base::Time* updated_time); | |
| 118 | |
| 119 // Returns true if the maximum number of points today has been added. | |
| 120 bool MaxPointsPerDayAdded() const; | |
| 121 | |
| 122 // Get/set the last time this origin was launched from an installed shortcut. | |
| 123 base::Time last_shortcut_launch_time() const { | |
| 124 return last_shortcut_launch_time_; | |
| 125 } | |
| 126 void set_last_shortcut_launch_time(const base::Time& time) { | |
| 127 last_shortcut_launch_time_ = time; | |
| 128 } | |
| 129 | |
| 130 // Updates the content settings dictionary |score_dict| with the current score | |
| 131 // fields. Returns true if |score_dict| changed, otherwise return false. | |
| 132 bool UpdateScoreDict(base::DictionaryValue* score_dict); | |
| 133 | |
| 134 private: | |
| 135 FRIEND_TEST_ALL_PREFIXES(SiteEngagementScoreTest, PartiallyEmptyDictionary); | |
| 136 FRIEND_TEST_ALL_PREFIXES(SiteEngagementScoreTest, PopulatedDictionary); | |
| 137 FRIEND_TEST_ALL_PREFIXES(SiteEngagementScoreTest, Reset); | |
| 138 FRIEND_TEST_ALL_PREFIXES(SiteEngagementScoreTest, FirstDailyEngagementBonus); | |
| 139 friend class SiteEngagementHelperTest; | |
| 140 friend class SiteEngagementScoreTest; | |
| 141 friend class SiteEngagementServiceTest; | |
| 142 friend class ImportantSitesUtilTest; | |
| 143 | |
| 144 // Array holding the values corresponding to each item in Variation array. | |
| 145 static double param_values[]; | |
| 146 | |
| 147 // Keys used in the content settings dictionary. | |
| 148 static const char* kRawScoreKey; | |
| 149 static const char* kPointsAddedTodayKey; | |
| 150 static const char* kLastEngagementTimeKey; | |
| 151 static const char* kLastShortcutLaunchTimeKey; | |
| 152 | |
| 153 // This version of the constructor is used in unit tests. | |
| 154 explicit SiteEngagementScore(base::Clock* clock); | |
| 155 | |
| 156 // Determine the score, accounting for any decay. | |
| 157 double DecayedScore() const; | |
| 158 | |
| 159 // Determine any score bonus from having installed shortcuts. | |
| 160 double BonusScore() const; | |
| 161 | |
| 162 // Sets fixed parameter values for testing site engagement. Ensure that any | |
| 163 // newly added parameters receive a fixed value here. | |
| 164 static void SetParamValuesForTesting(); | |
| 165 | |
| 166 // The clock used to vend times. Enables time travelling in tests. Owned by | |
| 167 // the SiteEngagementService. | |
| 168 base::Clock* clock_; | |
| 169 | |
| 170 // |raw_score_| is the score before any decay is applied. | |
| 171 double raw_score_; | |
| 172 | |
| 173 // The points added 'today' are tracked to avoid adding more than | |
| 174 // kMaxPointsPerDay on any one day. 'Today' is defined in local time. | |
| 175 double points_added_today_; | |
| 176 | |
| 177 // The last time the score was updated for engagement. Used in conjunction | |
| 178 // with |points_added_today_| to avoid adding more than kMaxPointsPerDay on | |
| 179 // any one day. | |
| 180 base::Time last_engagement_time_; | |
| 181 | |
| 182 // The last time the site with this score was launched from an installed | |
| 183 // shortcut. | |
| 184 base::Time last_shortcut_launch_time_; | |
| 185 | |
| 186 DISALLOW_COPY_AND_ASSIGN(SiteEngagementScore); | |
| 187 }; | |
| 188 | |
| 189 class SiteEngagementScoreProvider { | 33 class SiteEngagementScoreProvider { |
| 190 public: | 34 public: |
| 191 // Returns a non-negative integer representing the engagement score of the | 35 // Returns a non-negative integer representing the engagement score of the |
| 192 // origin for this URL. | 36 // origin for this URL. |
| 193 virtual double GetScore(const GURL& url) const = 0; | 37 virtual double GetScore(const GURL& url) const = 0; |
| 194 | 38 |
| 195 // Returns the sum of engagement points awarded to all sites. | 39 // Returns the sum of engagement points awarded to all sites. |
| 196 virtual double GetTotalEngagementPoints() const = 0; | 40 virtual double GetTotalEngagementPoints() const = 0; |
| 197 }; | 41 }; |
| 198 | 42 |
| 199 // Stores and retrieves the engagement score of an origin. | 43 // Stores and retrieves the engagement score of an origin. |
| 200 // | 44 // |
| 201 // An engagement score is a positive integer that represents how much a user has | 45 // An engagement score is a positive integer that represents how much a user has |
| 202 // engaged with an origin - the higher it is, the more engagement the user has | 46 // engaged with an origin - the higher it is, the more engagement the user has |
| 203 // had with this site recently. | 47 // had with this site recently. |
| 204 // | 48 // |
| 205 // Positive user activity, such as visiting the origin often and adding it to | 49 // Positive user activity, such as visiting the origin often and adding it to |
| 206 // the homescreen, will increase the site engagement score. Negative activity, | 50 // the homescreen, will increase the site engagement score. Negative activity, |
| 207 // such as rejecting permission prompts or not responding to notifications, will | 51 // such as rejecting permission prompts or not responding to notifications, will |
| 208 // decrease the site engagement score. | 52 // decrease the site engagement score. |
| 209 class SiteEngagementService : public KeyedService, | 53 class SiteEngagementService : public KeyedService, |
| 210 public history::HistoryServiceObserver, | 54 public history::HistoryServiceObserver, |
| 211 public SiteEngagementScoreProvider { | 55 public SiteEngagementScoreProvider { |
| 212 public: | 56 public: |
| 57 // WebContentsObserver that detects engagement triggering events and notifies | |
|
calamity
2016/05/16 04:35:49
nit: double space at line-start
dominickn
2016/05/16 04:53:05
Done.
| |
| 58 // the service of them. | |
| 59 class Helper; | |
| 60 | |
| 213 enum EngagementLevel { | 61 enum EngagementLevel { |
| 214 ENGAGEMENT_LEVEL_NONE, | 62 ENGAGEMENT_LEVEL_NONE, |
| 215 ENGAGEMENT_LEVEL_LOW, | 63 ENGAGEMENT_LEVEL_LOW, |
| 216 ENGAGEMENT_LEVEL_MEDIUM, | 64 ENGAGEMENT_LEVEL_MEDIUM, |
| 217 ENGAGEMENT_LEVEL_HIGH, | 65 ENGAGEMENT_LEVEL_HIGH, |
| 218 ENGAGEMENT_LEVEL_MAX, | 66 ENGAGEMENT_LEVEL_MAX, |
| 219 }; | 67 }; |
| 220 | 68 |
| 221 // The name of the site engagement variation field trial. | 69 // The name of the site engagement variation field trial. |
| 222 static const char kEngagementParams[]; | 70 static const char kEngagementParams[]; |
| 223 | 71 |
| 72 // Returns the site engagement service attached to this profile. May return | |
| 73 // null if the service does not exist (e.g. the user is in incognito). | |
| 224 static SiteEngagementService* Get(Profile* profile); | 74 static SiteEngagementService* Get(Profile* profile); |
| 225 | 75 |
| 226 // Returns whether or not the SiteEngagementService is enabled. | 76 // Returns the maximum possible amount of engagement that a site can accrue. |
| 77 static double GetMaxPoints(); | |
| 78 | |
| 79 // Returns whether or not the site engagement service is enabled. | |
| 227 static bool IsEnabled(); | 80 static bool IsEnabled(); |
| 228 | 81 |
| 229 explicit SiteEngagementService(Profile* profile); | 82 explicit SiteEngagementService(Profile* profile); |
| 230 ~SiteEngagementService() override; | 83 ~SiteEngagementService() override; |
| 231 | 84 |
| 85 // Returns the engagement level of |url|. This is the recommended API for | |
| 86 // clients | |
| 87 EngagementLevel GetEngagementLevel(const GURL& url) const; | |
| 88 | |
| 232 // Returns a map of all stored origins and their engagement scores. | 89 // Returns a map of all stored origins and their engagement scores. |
| 233 std::map<GURL, double> GetScoreMap() const; | 90 std::map<GURL, double> GetScoreMap() const; |
| 234 | 91 |
| 235 // Returns whether the engagement service has enough data to make meaningful | 92 // Returns whether the engagement service has enough data to make meaningful |
| 236 // decisions. Clients should avoid using engagement in their heuristic until | 93 // decisions. Clients should avoid using engagement in their heuristic until |
| 237 // this is true. | 94 // this is true. |
| 238 bool IsBootstrapped(); | 95 bool IsBootstrapped(); |
| 239 | 96 |
| 240 // Returns the engagement level of |url|. This is the recommended API for | |
| 241 // clients | |
| 242 EngagementLevel GetEngagementLevel(const GURL& url) const; | |
| 243 | |
| 244 // Returns whether |url| has at least the given |level| of engagement. | 97 // Returns whether |url| has at least the given |level| of engagement. |
| 245 bool IsEngagementAtLeast(const GURL& url, EngagementLevel level) const; | 98 bool IsEngagementAtLeast(const GURL& url, EngagementLevel level) const; |
| 246 | 99 |
| 247 // Update the engagement score of the origin matching |url| for navigation. | |
| 248 void HandleNavigation(const GURL& url, ui::PageTransition transition); | |
| 249 | |
| 250 // Update the engagement score of the origin matching |url| for time-on-site, | |
| 251 // based on user input. | |
| 252 void HandleUserInput(const GURL& url, | |
| 253 SiteEngagementMetrics::EngagementType type); | |
| 254 | |
| 255 // Update the engagement score of the origin matching |url| for media playing. | |
| 256 // The points awarded are discounted if the media is being played in a non- | |
| 257 // visible tab. | |
| 258 void HandleMediaPlaying(const GURL& url, bool is_hidden); | |
| 259 | |
| 260 // Resets the engagement score |url| to |score|, clearing daily limits. | 100 // Resets the engagement score |url| to |score|, clearing daily limits. |
| 261 void ResetScoreForURL(const GURL& url, double score); | 101 void ResetScoreForURL(const GURL& url, double score); |
| 262 | 102 |
| 263 // Overridden from history::HistoryServiceObserver: | |
| 264 void OnURLsDeleted(history::HistoryService* history_service, | |
| 265 bool all_history, | |
| 266 bool expired, | |
| 267 const history::URLRows& deleted_rows, | |
| 268 const std::set<GURL>& favicon_urls) override; | |
| 269 | |
| 270 // Update the last time |url| was opened from an installed shortcut to be | 103 // Update the last time |url| was opened from an installed shortcut to be |
| 271 // clock_->Now(). | 104 // clock_->Now(). |
| 272 void SetLastShortcutLaunchTime(const GURL& url); | 105 void SetLastShortcutLaunchTime(const GURL& url); |
| 273 | 106 |
| 274 // Overridden from SiteEngagementScoreProvider: | 107 // Overridden from SiteEngagementScoreProvider: |
| 275 double GetScore(const GURL& url) const override; | 108 double GetScore(const GURL& url) const override; |
| 276 double GetTotalEngagementPoints() const override; | 109 double GetTotalEngagementPoints() const override; |
| 277 | 110 |
| 278 private: | 111 private: |
| 279 FRIEND_TEST_ALL_PREFIXES(SiteEngagementServiceTest, CheckHistograms); | 112 FRIEND_TEST_ALL_PREFIXES(SiteEngagementServiceTest, CheckHistograms); |
| 280 FRIEND_TEST_ALL_PREFIXES(SiteEngagementServiceTest, CleanupEngagementScores); | 113 FRIEND_TEST_ALL_PREFIXES(SiteEngagementServiceTest, CleanupEngagementScores); |
| 281 FRIEND_TEST_ALL_PREFIXES(SiteEngagementServiceTest, ClearHistoryForURLs); | 114 FRIEND_TEST_ALL_PREFIXES(SiteEngagementServiceTest, ClearHistoryForURLs); |
| 282 FRIEND_TEST_ALL_PREFIXES(SiteEngagementServiceTest, GetMedianEngagement); | 115 FRIEND_TEST_ALL_PREFIXES(SiteEngagementServiceTest, GetMedianEngagement); |
| 283 FRIEND_TEST_ALL_PREFIXES(SiteEngagementServiceTest, GetTotalNavigationPoints); | 116 FRIEND_TEST_ALL_PREFIXES(SiteEngagementServiceTest, GetTotalNavigationPoints); |
| 284 FRIEND_TEST_ALL_PREFIXES(SiteEngagementServiceTest, GetTotalUserInputPoints); | 117 FRIEND_TEST_ALL_PREFIXES(SiteEngagementServiceTest, GetTotalUserInputPoints); |
| 285 FRIEND_TEST_ALL_PREFIXES(SiteEngagementServiceTest, LastShortcutLaunch); | 118 FRIEND_TEST_ALL_PREFIXES(SiteEngagementServiceTest, LastShortcutLaunch); |
| 286 FRIEND_TEST_ALL_PREFIXES(SiteEngagementServiceTest, | 119 FRIEND_TEST_ALL_PREFIXES(SiteEngagementServiceTest, |
| 287 CleanupOriginsOnHistoryDeletion); | 120 CleanupOriginsOnHistoryDeletion); |
| 288 FRIEND_TEST_ALL_PREFIXES(SiteEngagementServiceTest, IsBootstrapped); | 121 FRIEND_TEST_ALL_PREFIXES(SiteEngagementServiceTest, IsBootstrapped); |
| 289 FRIEND_TEST_ALL_PREFIXES(SiteEngagementServiceTest, EngagementLevel); | 122 FRIEND_TEST_ALL_PREFIXES(SiteEngagementServiceTest, EngagementLevel); |
| 290 FRIEND_TEST_ALL_PREFIXES(SiteEngagementServiceTest, ScoreDecayHistograms); | 123 FRIEND_TEST_ALL_PREFIXES(SiteEngagementServiceTest, ScoreDecayHistograms); |
| 291 FRIEND_TEST_ALL_PREFIXES(AppBannerSettingsHelperTest, SiteEngagementTrigger); | 124 FRIEND_TEST_ALL_PREFIXES(AppBannerSettingsHelperTest, SiteEngagementTrigger); |
| 292 FRIEND_TEST_ALL_PREFIXES(ImportantSitesUtilTest, NotificationsThenEngagement); | |
| 293 | 125 |
| 294 // Only used in tests. | 126 // Only used in tests. |
| 295 SiteEngagementService(Profile* profile, std::unique_ptr<base::Clock> clock); | 127 SiteEngagementService(Profile* profile, std::unique_ptr<base::Clock> clock); |
| 296 | 128 |
| 297 // Adds the specified number of points to the given origin, respecting the | 129 // Adds the specified number of points to the given origin, respecting the |
| 298 // maximum limits for the day and overall. | 130 // maximum limits for the day and overall. |
| 299 void AddPoints(const GURL& url, double points); | 131 void AddPoints(const GURL& url, double points); |
| 300 | 132 |
| 301 // Post startup tasks: cleaning up origins which have decayed to 0, and | 133 // Post startup tasks: cleaning up origins which have decayed to 0, and |
| 302 // logging UMA statistics. | 134 // logging UMA statistics. |
| 303 void AfterStartupTask(); | 135 void AfterStartupTask(); |
| 304 void CleanupEngagementScores(); | 136 void CleanupEngagementScores(); |
| 305 void RecordMetrics(); | 137 void RecordMetrics(); |
| 306 | 138 |
| 307 // Returns the median engagement score of all recorded origins. | 139 // Returns the median engagement score of all recorded origins. |
| 308 double GetMedianEngagement(const std::map<GURL, double>& score_map) const; | 140 double GetMedianEngagement(const std::map<GURL, double>& score_map) const; |
| 309 | 141 |
| 142 // Update the engagement score of the origin matching |url| for media playing. | |
| 143 // The points awarded are discounted if the media is being played in a non- | |
| 144 // visible tab. | |
| 145 void HandleMediaPlaying(const GURL& url, bool is_hidden); | |
| 146 | |
| 147 // Update the engagement score of the origin matching |url| for navigation. | |
| 148 void HandleNavigation(const GURL& url, ui::PageTransition transition); | |
| 149 | |
| 150 // Update the engagement score of the origin matching |url| for time-on-site, | |
| 151 // based on user input. | |
| 152 void HandleUserInput(const GURL& url, | |
| 153 SiteEngagementMetrics::EngagementType type); | |
| 154 | |
| 155 // Overridden from history::HistoryServiceObserver: | |
| 156 void OnURLsDeleted(history::HistoryService* history_service, | |
| 157 bool all_history, | |
| 158 bool expired, | |
| 159 const history::URLRows& deleted_rows, | |
| 160 const std::set<GURL>& favicon_urls) override; | |
| 161 | |
| 310 // Returns the number of origins with maximum daily and total engagement | 162 // Returns the number of origins with maximum daily and total engagement |
| 311 // respectively. | 163 // respectively. |
| 312 int OriginsWithMaxDailyEngagement() const; | 164 int OriginsWithMaxDailyEngagement() const; |
| 313 int OriginsWithMaxEngagement(const std::map<GURL, double>& score_map) const; | 165 int OriginsWithMaxEngagement(const std::map<GURL, double>& score_map) const; |
| 314 | 166 |
| 315 void GetCountsAndLastVisitForOriginsComplete( | 167 void GetCountsAndLastVisitForOriginsComplete( |
| 316 history::HistoryService* history_service, | 168 history::HistoryService* history_service, |
| 317 const std::multiset<GURL>& deleted_url_origins, | 169 const std::multiset<GURL>& deleted_url_origins, |
| 318 bool expired, | 170 bool expired, |
| 319 const history::OriginCountAndLastVisitMap& remaining_origin_counts); | 171 const history::OriginCountAndLastVisitMap& remaining_origin_counts); |
| (...skipping 16 matching lines...) Expand all Loading... | |
| 336 // origin's engagement score after an hour has elapsed triggers the next | 188 // origin's engagement score after an hour has elapsed triggers the next |
| 337 // upload. | 189 // upload. |
| 338 base::Time last_metrics_time_; | 190 base::Time last_metrics_time_; |
| 339 | 191 |
| 340 base::WeakPtrFactory<SiteEngagementService> weak_factory_; | 192 base::WeakPtrFactory<SiteEngagementService> weak_factory_; |
| 341 | 193 |
| 342 DISALLOW_COPY_AND_ASSIGN(SiteEngagementService); | 194 DISALLOW_COPY_AND_ASSIGN(SiteEngagementService); |
| 343 }; | 195 }; |
| 344 | 196 |
| 345 #endif // CHROME_BROWSER_ENGAGEMENT_SITE_ENGAGEMENT_SERVICE_H_ | 197 #endif // CHROME_BROWSER_ENGAGEMENT_SITE_ENGAGEMENT_SERVICE_H_ |
| OLD | NEW |