Chromium Code Reviews| Index: chrome/browser/ui/tabs/tab_utils.cc |
| diff --git a/chrome/browser/ui/tabs/tab_utils.cc b/chrome/browser/ui/tabs/tab_utils.cc |
| index cfe6282b03aeb2d6ad9a80104fae4874f394a759..d320b87c98ea5b349659a4a826e8a56598378ba8 100644 |
| --- a/chrome/browser/ui/tabs/tab_utils.cc |
| +++ b/chrome/browser/ui/tabs/tab_utils.cc |
| @@ -21,8 +21,15 @@ struct LastMuteMetadata |
| : public content::WebContentsUserData<LastMuteMetadata> { |
| std::string cause; // Extension ID or constant from header file |
| // or empty string |
| + base::TimeDelta token_bucket; |
| + base::TimeTicks last_attempt; |
| + |
| private: |
| - explicit LastMuteMetadata(content::WebContents* contents) {} |
| + explicit LastMuteMetadata(content::WebContents* contents) { |
| + token_bucket = |
| + base::TimeDelta::FromSeconds(chrome::kMuteTokenBucketCapacitySeconds); |
| + last_attempt = base::TimeTicks::Now(); |
| + } |
| friend class content::WebContentsUserData<LastMuteMetadata>; |
| }; |
| @@ -32,6 +39,8 @@ namespace chrome { |
| const char kMutedToggleCauseUser[] = "user"; |
| const char kMutedToggleCauseCapture[] = "capture"; |
| +const int kMuteTokenBucketCostSeconds = 15; |
| +const int kMuteTokenBucketCapacitySeconds = 3 * kMuteTokenBucketCostSeconds; |
| namespace { |
| @@ -91,6 +100,31 @@ TabRecordingIndicatorAnimation::Create() { |
| return animation.Pass(); |
| } |
| +// Only run when cause should be rate limited (i.e. extensions) |
| +void UpdateTokenBuckets(content::WebContents* contents) { |
| + DCHECK(contents); |
|
miu
2015/07/18 00:42:42
To answer your question: The DCHECK here and at th
Jared Sohn
2015/07/18 23:57:24
I am removing them and replacing with a general co
|
| + |
| + base::TimeTicks now = base::TimeTicks::Now(); |
| + base::TimeDelta elapsed_since_last_attempt = |
| + now - LastMuteMetadata::FromWebContents(contents)->last_attempt; |
| + LastMuteMetadata::FromWebContents(contents)->last_attempt = now; |
| + |
| + // Add tokens to the bucket, proportional to how much time has elapsed, capped |
| + // at the maximum capacity. |
| + LastMuteMetadata::FromWebContents(contents)->token_bucket = std::min( |
| + base::TimeDelta::FromSeconds(chrome::kMuteTokenBucketCapacitySeconds), |
| + LastMuteMetadata::FromWebContents(contents)->token_bucket + |
| + elapsed_since_last_attempt); |
| +} |
| + |
| +// Only run when cause should be rate limited (i.e. extensions) |
| +bool IsTabAudioMutedRateLimited(content::WebContents* contents) { |
| + DCHECK(contents); |
| + |
| + return (LastMuteMetadata::FromWebContents(contents)->token_bucket < |
| + base::TimeDelta::FromSeconds(kMuteTokenBucketCostSeconds)); |
| +} |
| + |
| } // namespace |
| bool ShouldTabShowFavicon(int capacity, |
| @@ -276,16 +310,34 @@ const std::string& GetTabAudioMutedCause(content::WebContents* contents) { |
| return LastMuteMetadata::FromWebContents(contents)->cause; |
| } |
| -void SetTabAudioMuted(content::WebContents* contents, |
| - bool mute, |
| - const std::string& cause) { |
| - if (!contents || !chrome::CanToggleAudioMute(contents)) |
| - return; |
| +TabMutedResult SetTabAudioMuted(content::WebContents* contents, |
| + bool mute, |
| + const std::string& cause) { |
| + DCHECK(contents); |
| + |
| + if (!IsTabAudioMutingFeatureEnabled()) |
| + return TAB_MUTED_RESULT_FAIL_NOT_ENABLED; |
| + |
| + if (!chrome::CanToggleAudioMute(contents)) |
| + return TAB_MUTED_RESULT_FAIL_TABCAPTURE; |
| LastMuteMetadata::CreateForWebContents(contents); // Create if not exists. |
| + |
| + if ((cause != kMutedToggleCauseUser) && (cause != kMutedToggleCauseCapture)) { |
| + UpdateTokenBuckets(contents); |
| + |
| + if (IsTabAudioMutedRateLimited(contents)) |
| + return TAB_MUTED_RESULT_FAIL_RATE_LIMITED; |
| + |
| + LastMuteMetadata::FromWebContents(contents)->token_bucket -= |
| + base::TimeDelta::FromSeconds(kMuteTokenBucketCostSeconds); |
| + } |
| + |
| LastMuteMetadata::FromWebContents(contents)->cause = cause; |
| contents->SetAudioMuted(mute); |
| + |
| + return TAB_MUTED_RESULT_SUCCESS; |
| } |
| bool IsTabAudioMuted(content::WebContents* contents) { |