1a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)// Copyright 2014 The Chromium Authors. All rights reserved.
2a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
3a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)// found in the LICENSE file.
4a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
5a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#include "ash/system/audio/tray_audio.h"
6a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
7a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#include <cmath>
8a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
9a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#include "ash/ash_constants.h"
10a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#include "ash/metrics/user_metrics_recorder.h"
11a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#include "ash/shell.h"
12a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#include "ash/system/audio/tray_audio_delegate.h"
13a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#include "ash/system/audio/volume_view.h"
14a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#include "ash/system/tray/actionable_view.h"
15a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#include "ash/system/tray/fixed_sized_scroll_view.h"
16a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#include "ash/system/tray/hover_highlight_view.h"
17a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#include "ash/system/tray/system_tray.h"
18a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#include "ash/system/tray/system_tray_delegate.h"
19a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#include "ash/system/tray/system_tray_notifier.h"
20a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#include "ash/system/tray/tray_constants.h"
21a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#include "ash/volume_control_delegate.h"
22a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#include "base/strings/utf_string_conversions.h"
23a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#include "grit/ash_resources.h"
24a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#include "third_party/skia/include/core/SkCanvas.h"
25a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#include "third_party/skia/include/core/SkPaint.h"
26a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#include "third_party/skia/include/core/SkRect.h"
27a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#include "third_party/skia/include/effects/SkGradientShader.h"
28a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#include "ui/gfx/canvas.h"
29a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#include "ui/gfx/font_list.h"
30a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#include "ui/gfx/image/image.h"
31a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#include "ui/gfx/image/image_skia_operations.h"
32a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#include "ui/views/controls/button/image_button.h"
33a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#include "ui/views/controls/image_view.h"
34a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#include "ui/views/controls/label.h"
35a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#include "ui/views/controls/slider.h"
36a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#include "ui/views/layout/box_layout.h"
37a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#include "ui/views/view.h"
38a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
39a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)namespace ash {
40a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
41a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)TrayAudio::TrayAudio(SystemTray* system_tray,
42a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                     scoped_ptr<system::TrayAudioDelegate> audio_delegate)
43a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    : TrayImageItem(system_tray, IDR_AURA_UBER_TRAY_VOLUME_MUTE),
44a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      audio_delegate_(audio_delegate.Pass()),
45a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      volume_view_(NULL),
46a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      pop_up_volume_view_(false) {
47a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  Shell::GetInstance()->system_tray_notifier()->AddAudioObserver(this);
48a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)}
49a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
50a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)TrayAudio::~TrayAudio() {
51a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  Shell::GetInstance()->system_tray_notifier()->RemoveAudioObserver(this);
52a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)}
53a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
54a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)// static
55a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)bool TrayAudio::ShowAudioDeviceMenu() {
56a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#if defined(OS_CHROMEOS)
57a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  return true;
58a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#else
59a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  return false;
60a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#endif
61a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)}
62a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
63a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)bool TrayAudio::GetInitialVisibility() {
64a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  return audio_delegate_->IsOutputAudioMuted();
65a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)}
66a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
67a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)views::View* TrayAudio::CreateDefaultView(user::LoginStatus status) {
68a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  volume_view_ = new tray::VolumeView(this, audio_delegate_.get(), true);
69a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  return volume_view_;
70a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)}
71a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
72a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)views::View* TrayAudio::CreateDetailedView(user::LoginStatus status) {
73a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  volume_view_ = new tray::VolumeView(this, audio_delegate_.get(), false);
74a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  return volume_view_;
75a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)}
76a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
77a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)void TrayAudio::DestroyDefaultView() {
78a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  volume_view_ = NULL;
79a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)}
80a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
81a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)void TrayAudio::DestroyDetailedView() {
82a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  if (volume_view_) {
83a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    volume_view_ = NULL;
84a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    pop_up_volume_view_ = false;
85a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  }
86a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)}
87a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
88a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)bool TrayAudio::ShouldHideArrow() const {
89a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  return true;
90a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)}
91a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
92a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)bool TrayAudio::ShouldShowShelf() const {
93a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  return TrayAudio::ShowAudioDeviceMenu() && !pop_up_volume_view_;
94a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)}
95a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
96a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)void TrayAudio::OnOutputVolumeChanged() {
97a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  float percent =
98a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      static_cast<float>(audio_delegate_->GetOutputVolumeLevel()) / 100.0f;
99a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  if (tray_view())
100a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    tray_view()->SetVisible(GetInitialVisibility());
101a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
102a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  if (volume_view_) {
103a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    volume_view_->SetVolumeLevel(percent);
104a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    SetDetailedViewCloseDelay(kTrayPopupAutoCloseDelayInSeconds);
105a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    return;
106a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  }
107a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  pop_up_volume_view_ = true;
108a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  PopupDetailedView(kTrayPopupAutoCloseDelayInSeconds, false);
109a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)}
110a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
111a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)void TrayAudio::OnOutputMuteChanged() {
112a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  if (tray_view())
113a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      tray_view()->SetVisible(GetInitialVisibility());
114a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
115a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  if (volume_view_) {
116a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    volume_view_->Update();
117a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    SetDetailedViewCloseDelay(kTrayPopupAutoCloseDelayInSeconds);
118a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  } else {
119a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    pop_up_volume_view_ = true;
120a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    PopupDetailedView(kTrayPopupAutoCloseDelayInSeconds, false);
121a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  }
122a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)}
123a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
124a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)void TrayAudio::OnAudioNodesChanged() {
125a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  Update();
126a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)}
127a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
128a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)void TrayAudio::OnActiveOutputNodeChanged() {
129a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  Update();
130a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)}
131a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
132a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)void TrayAudio::OnActiveInputNodeChanged() {
133a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  Update();
134a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)}
135a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
136a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)void TrayAudio::Update() {
137a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  if (tray_view())
138a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      tray_view()->SetVisible(GetInitialVisibility());
139a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  if (volume_view_) {
140a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    volume_view_->SetVolumeLevel(
141a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)        static_cast<float>(audio_delegate_->GetOutputVolumeLevel()) / 100.0f);
142a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    volume_view_->Update();
143a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  }
144a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)}
145a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
146a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)}  // namespace ash
147