1 // Copyright 2017 The Chromium Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 5 #ifndef CHROME_BROWSER_MEDIA_MEDIA_ENGAGEMENT_SCORE_H_ 6 #define CHROME_BROWSER_MEDIA_MEDIA_ENGAGEMENT_SCORE_H_ 7 8 #include <memory> 9 10 #include "base/macros.h" 11 #include "base/time/clock.h" 12 #include "base/values.h" 13 #include "chrome/browser/media/media_engagement_score_details.mojom.h" 14 #include "components/content_settings/core/browser/host_content_settings_map.h" 15 #include "url/origin.h" 16 17 class HostContentSettingsMap; 18 19 // Calculates and stores the Media Engagement Index score for a certain origin. 20 class MediaEngagementScore final { 21 public: 22 // The dictionary keys to store individual metrics. kVisitsKey will store the 23 // number of visits to an origin and kMediaPlaybacksKey will store the number 24 // of media playbacks on an origin. kLastMediaPlaybackTimeKey will store the 25 // timestamp of the last media playback on an origin. kHasHighScoreKey will 26 // store whether the score is considered high. 27 static const char kVisitsKey[]; 28 static const char kMediaPlaybacksKey[]; 29 static const char kLastMediaPlaybackTimeKey[]; 30 static const char kHasHighScoreKey[]; 31 32 // Origins with a number of visits less than this number will recieve 33 // a score of zero. 34 static int GetScoreMinVisits(); 35 36 // The upper and lower threshold of whether the total score is considered 37 // to be high. 38 static double GetHighScoreLowerThreshold(); 39 static double GetHighScoreUpperThreshold(); 40 41 MediaEngagementScore(base::Clock* clock, 42 const url::Origin& origin, 43 HostContentSettingsMap* settings); 44 ~MediaEngagementScore(); 45 46 MediaEngagementScore(MediaEngagementScore&&); 47 MediaEngagementScore& operator=(MediaEngagementScore&&); 48 49 // Returns the total score, as per the formula. actual_score()50 double actual_score() const { return actual_score_; } 51 52 // Returns whether the total score is considered high. high_score()53 bool high_score() const { return is_high_; } 54 55 // Returns the origin associated with this score. origin()56 const url::Origin& origin() const { return origin_; } 57 58 // Writes the values in this score into |settings_map_|. If there are multiple 59 // instances of a score object for an origin, this could result in stale data 60 // being stored. 61 void Commit(); 62 63 // Get/increment the number of visits this origin has had. visits()64 int visits() const { return visits_; } IncrementVisits()65 void IncrementVisits() { SetVisits(visits() + 1); } 66 67 // Get/increment the number of media playbacks this origin has had. media_playbacks()68 int media_playbacks() const { return media_playbacks_; } 69 void IncrementMediaPlaybacks(); 70 71 // Gets/sets the last time media was played on this origin. last_media_playback_time()72 base::Time last_media_playback_time() const { 73 return last_media_playback_time_; 74 } set_last_media_playback_time(base::Time new_time)75 void set_last_media_playback_time(base::Time new_time) { 76 last_media_playback_time_ = new_time; 77 } 78 79 // Get a breakdown of the score that can be serialized by Mojo. 80 media::mojom::MediaEngagementScoreDetailsPtr GetScoreDetails() const; 81 82 protected: 83 friend class MediaEngagementAutoplayBrowserTest; 84 friend class MediaEngagementContentsObserverTest; 85 friend class MediaEngagementSessionTest; 86 friend class MediaEngagementService; 87 88 // Only used by the Media Engagement service when bulk loading data. 89 MediaEngagementScore(base::Clock* clock, 90 const url::Origin& origin, 91 std::unique_ptr<base::DictionaryValue> score_dict, 92 HostContentSettingsMap* settings); 93 94 static const char kScoreMinVisitsParamName[]; 95 static const char kHighScoreLowerThresholdParamName[]; 96 static const char kHighScoreUpperThresholdParamName[]; 97 98 void SetVisits(int visits); 99 void SetMediaPlaybacks(int media_playbacks); 100 101 private: 102 friend class MediaEngagementServiceTest; 103 friend class MediaEngagementScoreTest; 104 105 // Update the dictionary continaing the latest score values and return whether 106 // they have changed or not (since what was last retrieved from content 107 // settings). 108 bool UpdateScoreDict(); 109 110 // If the number of playbacks or visits is updated then this will recalculate 111 // the total score and whether the score is considered high. 112 void Recalculate(); 113 114 // The number of media playbacks this origin has had. 115 int media_playbacks_ = 0; 116 117 // The number of visits this origin has had. 118 int visits_ = 0; 119 120 // If the current score is considered high. 121 bool is_high_ = false; 122 123 // The current engagement score. 124 double actual_score_ = 0.0; 125 126 // The last time media was played back on this origin. 127 base::Time last_media_playback_time_; 128 129 // The origin this score represents. 130 url::Origin origin_; 131 132 // A clock that can be used for testing, owned by the service. 133 base::Clock* clock_; 134 135 // The dictionary that represents this engagement score. 136 std::unique_ptr<base::DictionaryValue> score_dict_; 137 138 // The content settings map that will persist the score, 139 // has a lifetime of the Profile like the service which owns |this|. 140 HostContentSettingsMap* settings_map_ = nullptr; 141 142 DISALLOW_COPY_AND_ASSIGN(MediaEngagementScore); 143 }; 144 145 #endif // CHROME_BROWSER_MEDIA_MEDIA_ENGAGEMENT_SCORE_H_ 146