This source file includes following definitions.
- GetCurrentValue
- Create
- ShouldTabShowFavicon
- ShouldTabShowMediaIndicator
- ShouldTabShowCloseButton
- IsPlayingAudio
- GetTabMediaStateForContents
- GetTabMediaIndicatorImage
- CreateTabMediaIndicatorFadeAnimation
- AssembleTabTooltipText
#include "chrome/browser/ui/tabs/tab_utils.h"
#include "base/strings/string16.h"
#include "chrome/browser/media/audio_stream_monitor.h"
#include "chrome/browser/media/media_capture_devices_dispatcher.h"
#include "chrome/browser/media/media_stream_capture_indicator.h"
#include "grit/generated_resources.h"
#include "grit/theme_resources.h"
#include "ui/base/l10n/l10n_util.h"
#include "ui/base/resource/resource_bundle.h"
#include "ui/gfx/animation/multi_animation.h"
namespace chrome {
namespace {
const int kIndicatorFrameIntervalMs = 50;
const int kIndicatorFadeInDurationMs = 200;
const int kIndicatorFadeOutDurationMs = 1000;
class TabRecordingIndicatorAnimation : public gfx::MultiAnimation {
public:
virtual ~TabRecordingIndicatorAnimation() {}
virtual double GetCurrentValue() const OVERRIDE;
static scoped_ptr<TabRecordingIndicatorAnimation> Create();
private:
TabRecordingIndicatorAnimation(const gfx::MultiAnimation::Parts& parts,
const base::TimeDelta interval)
: MultiAnimation(parts, interval) {}
static const int kCaptureIndicatorThrobCycles = 5;
};
double TabRecordingIndicatorAnimation::GetCurrentValue() const {
return current_part_index() % 2 ?
1.0 - MultiAnimation::GetCurrentValue() :
MultiAnimation::GetCurrentValue();
}
scoped_ptr<TabRecordingIndicatorAnimation>
TabRecordingIndicatorAnimation::Create() {
MultiAnimation::Parts parts;
COMPILE_ASSERT(kCaptureIndicatorThrobCycles % 2 != 0,
must_be_odd_so_animation_finishes_in_showing_state);
for (int i = 0; i < kCaptureIndicatorThrobCycles; ++i) {
parts.push_back(MultiAnimation::Part(
i % 2 ? kIndicatorFadeOutDurationMs : kIndicatorFadeInDurationMs,
gfx::Tween::EASE_IN));
}
const base::TimeDelta interval =
base::TimeDelta::FromMilliseconds(kIndicatorFrameIntervalMs);
scoped_ptr<TabRecordingIndicatorAnimation> animation(
new TabRecordingIndicatorAnimation(parts, interval));
animation->set_continuous(false);
return animation.Pass();
}
}
bool ShouldTabShowFavicon(int capacity,
bool is_pinned_tab,
bool is_active_tab,
bool has_favicon,
TabMediaState media_state) {
if (!has_favicon)
return false;
int required_capacity = 1;
if (ShouldTabShowCloseButton(capacity, is_pinned_tab, is_active_tab))
++required_capacity;
if (ShouldTabShowMediaIndicator(
capacity, is_pinned_tab, is_active_tab, has_favicon, media_state)) {
++required_capacity;
}
return capacity >= required_capacity;
}
bool ShouldTabShowMediaIndicator(int capacity,
bool is_pinned_tab,
bool is_active_tab,
bool has_favicon,
TabMediaState media_state) {
if (media_state == TAB_MEDIA_STATE_NONE)
return false;
if (ShouldTabShowCloseButton(capacity, is_pinned_tab, is_active_tab))
return capacity >= 2;
return capacity >= 1;
}
bool ShouldTabShowCloseButton(int capacity,
bool is_pinned_tab,
bool is_active_tab) {
if (is_pinned_tab)
return false;
else if (is_active_tab)
return true;
else
return capacity >= 3;
}
bool IsPlayingAudio(content::WebContents* contents) {
AudioStreamMonitor* const audio_stream_monitor =
AudioStreamMonitor::FromWebContents(contents);
return audio_stream_monitor && audio_stream_monitor->WasRecentlyAudible();
}
TabMediaState GetTabMediaStateForContents(content::WebContents* contents) {
if (!contents)
return TAB_MEDIA_STATE_NONE;
scoped_refptr<MediaStreamCaptureIndicator> indicator =
MediaCaptureDevicesDispatcher::GetInstance()->
GetMediaStreamCaptureIndicator();
if (indicator) {
if (indicator->IsBeingMirrored(contents))
return TAB_MEDIA_STATE_CAPTURING;
if (indicator->IsCapturingUserMedia(contents))
return TAB_MEDIA_STATE_RECORDING;
}
if (IsPlayingAudio(contents))
return TAB_MEDIA_STATE_AUDIO_PLAYING;
return TAB_MEDIA_STATE_NONE;
}
const gfx::Image& GetTabMediaIndicatorImage(TabMediaState media_state) {
ui::ResourceBundle& rb = ui::ResourceBundle::GetSharedInstance();
switch (media_state) {
case TAB_MEDIA_STATE_AUDIO_PLAYING:
return rb.GetNativeImageNamed(IDR_TAB_AUDIO_INDICATOR);
case TAB_MEDIA_STATE_RECORDING:
return rb.GetNativeImageNamed(IDR_TAB_RECORDING_INDICATOR);
case TAB_MEDIA_STATE_CAPTURING:
return rb.GetNativeImageNamed(IDR_TAB_CAPTURE_INDICATOR);
case TAB_MEDIA_STATE_NONE:
break;
}
NOTREACHED();
return rb.GetNativeImageNamed(IDR_SAD_FAVICON);
}
scoped_ptr<gfx::Animation> CreateTabMediaIndicatorFadeAnimation(
TabMediaState media_state) {
if (media_state == TAB_MEDIA_STATE_RECORDING ||
media_state == TAB_MEDIA_STATE_CAPTURING) {
return TabRecordingIndicatorAnimation::Create().PassAs<gfx::Animation>();
}
gfx::MultiAnimation::Parts parts;
const bool is_for_fade_in = (media_state != TAB_MEDIA_STATE_NONE);
parts.push_back(gfx::MultiAnimation::Part(
is_for_fade_in ? kIndicatorFadeInDurationMs : kIndicatorFadeOutDurationMs,
gfx::Tween::EASE_IN));
const base::TimeDelta interval =
base::TimeDelta::FromMilliseconds(kIndicatorFrameIntervalMs);
scoped_ptr<gfx::MultiAnimation> animation(
new gfx::MultiAnimation(parts, interval));
animation->set_continuous(false);
return animation.PassAs<gfx::Animation>();
}
base::string16 AssembleTabTooltipText(const base::string16& title,
TabMediaState media_state) {
if (media_state == TAB_MEDIA_STATE_NONE)
return title;
base::string16 result = title;
if (!result.empty())
result.append(1, '\n');
switch (media_state) {
case TAB_MEDIA_STATE_AUDIO_PLAYING:
result.append(
l10n_util::GetStringUTF16(IDS_TOOLTIP_TAB_MEDIA_STATE_AUDIO_PLAYING));
break;
case TAB_MEDIA_STATE_RECORDING:
result.append(
l10n_util::GetStringUTF16(IDS_TOOLTIP_TAB_MEDIA_STATE_RECORDING));
break;
case TAB_MEDIA_STATE_CAPTURING:
result.append(
l10n_util::GetStringUTF16(IDS_TOOLTIP_TAB_MEDIA_STATE_CAPTURING));
break;
case TAB_MEDIA_STATE_NONE:
NOTREACHED();
break;
}
return result;
}
}