Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(283)

Side by Side Diff: ash/system/chromeos/audio/tray_audio.cc

Issue 165393013: Resubmit 'Refactor the TrayAudio code so that it can be used by other platforms.' (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Rebase to ToT Created 6 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « ash/system/chromeos/audio/tray_audio.h ('k') | ash/system/chromeos/audio/tray_audio_chromeos.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
1 // Copyright (c) 2012 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 #include "ash/system/chromeos/audio/tray_audio.h"
6
7 #include <cmath>
8
9 #include "ash/ash_constants.h"
10 #include "ash/ash_switches.h"
11 #include "ash/metrics/user_metrics_recorder.h"
12 #include "ash/shell.h"
13 #include "ash/system/tray/actionable_view.h"
14 #include "ash/system/tray/fixed_sized_scroll_view.h"
15 #include "ash/system/tray/hover_highlight_view.h"
16 #include "ash/system/tray/system_tray.h"
17 #include "ash/system/tray/system_tray_delegate.h"
18 #include "ash/system/tray/system_tray_notifier.h"
19 #include "ash/system/tray/tray_constants.h"
20 #include "ash/volume_control_delegate.h"
21 #include "base/strings/utf_string_conversions.h"
22 #include "chromeos/audio/cras_audio_handler.h"
23 #include "grit/ash_resources.h"
24 #include "grit/ash_strings.h"
25 #include "third_party/skia/include/core/SkCanvas.h"
26 #include "third_party/skia/include/core/SkPaint.h"
27 #include "third_party/skia/include/core/SkRect.h"
28 #include "third_party/skia/include/effects/SkGradientShader.h"
29 #include "ui/base/l10n/l10n_util.h"
30 #include "ui/base/resource/resource_bundle.h"
31 #include "ui/gfx/canvas.h"
32 #include "ui/gfx/font_list.h"
33 #include "ui/gfx/image/image.h"
34 #include "ui/gfx/image/image_skia_operations.h"
35 #include "ui/views/controls/button/image_button.h"
36 #include "ui/views/controls/image_view.h"
37 #include "ui/views/controls/label.h"
38 #include "ui/views/controls/slider.h"
39 #include "ui/views/layout/box_layout.h"
40 #include "ui/views/view.h"
41
42 using chromeos::CrasAudioHandler;
43
44 namespace ash {
45 namespace internal {
46
47 namespace {
48 const int kVolumeImageWidth = 25;
49 const int kVolumeImageHeight = 25;
50 const int kBarSeparatorWidth = 25;
51 const int kBarSeparatorHeight = 30;
52 const int kSliderRightPaddingToVolumeViewEdge = 17;
53 const int kExtraPaddingBetweenBarAndMore = 10;
54
55 const int kNoAudioDeviceIcon = -1;
56
57 // IDR_AURA_UBER_TRAY_VOLUME_LEVELS contains 5 images,
58 // The one for mute is at the 0 index and the other
59 // four are used for ascending volume levels.
60 const int kVolumeLevels = 4;
61
62 bool IsAudioMuted() {
63 return CrasAudioHandler::Get()->IsOutputMuted();
64 }
65
66 float GetVolumeLevel() {
67 return CrasAudioHandler::Get()->GetOutputVolumePercent() / 100.0f;
68 }
69
70 int GetAudioDeviceIconId(chromeos::AudioDeviceType type) {
71 if (type == chromeos::AUDIO_TYPE_HEADPHONE)
72 return IDR_AURA_UBER_TRAY_AUDIO_HEADPHONE;
73 else if (type == chromeos::AUDIO_TYPE_USB)
74 return IDR_AURA_UBER_TRAY_AUDIO_USB;
75 else if (type == chromeos::AUDIO_TYPE_BLUETOOTH)
76 return IDR_AURA_UBER_TRAY_AUDIO_BLUETOOTH;
77 else if (type == chromeos::AUDIO_TYPE_HDMI)
78 return IDR_AURA_UBER_TRAY_AUDIO_HDMI;
79 else
80 return kNoAudioDeviceIcon;
81 }
82
83 base::string16 GetAudioDeviceName(const chromeos::AudioDevice& device) {
84 switch(device.type) {
85 case chromeos::AUDIO_TYPE_HEADPHONE:
86 return l10n_util::GetStringUTF16(IDS_ASH_STATUS_TRAY_AUDIO_HEADPHONE);
87 case chromeos::AUDIO_TYPE_INTERNAL_SPEAKER:
88 return l10n_util::GetStringUTF16(
89 IDS_ASH_STATUS_TRAY_AUDIO_INTERNAL_SPEAKER);
90 case chromeos::AUDIO_TYPE_INTERNAL_MIC:
91 return l10n_util::GetStringUTF16(IDS_ASH_STATUS_TRAY_AUDIO_INTERNAL_MIC);
92 case chromeos::AUDIO_TYPE_USB:
93 return l10n_util::GetStringFUTF16(
94 IDS_ASH_STATUS_TRAY_AUDIO_USB_DEVICE,
95 base::UTF8ToUTF16(device.display_name));
96 case chromeos::AUDIO_TYPE_BLUETOOTH:
97 return l10n_util::GetStringFUTF16(
98 IDS_ASH_STATUS_TRAY_AUDIO_BLUETOOTH_DEVICE,
99 base::UTF8ToUTF16(device.display_name));
100 case chromeos::AUDIO_TYPE_HDMI:
101 return l10n_util::GetStringFUTF16(
102 IDS_ASH_STATUS_TRAY_AUDIO_HDMI_DEVICE,
103 base::UTF8ToUTF16(device.display_name));
104 default:
105 return base::UTF8ToUTF16(device.display_name);
106 }
107 }
108
109 } // namespace
110
111 namespace tray {
112
113 class VolumeButton : public views::ToggleImageButton {
114 public:
115 explicit VolumeButton(views::ButtonListener* listener)
116 : views::ToggleImageButton(listener),
117 image_index_(-1) {
118 SetImageAlignment(ALIGN_CENTER, ALIGN_MIDDLE);
119 image_ = ui::ResourceBundle::GetSharedInstance().GetImageNamed(
120 IDR_AURA_UBER_TRAY_VOLUME_LEVELS);
121 SetPreferredSize(gfx::Size(kTrayPopupItemHeight, kTrayPopupItemHeight));
122 Update();
123 }
124
125 virtual ~VolumeButton() {}
126
127 void Update() {
128 float level = GetVolumeLevel();
129 int image_index = IsAudioMuted() ?
130 0 : (level == 1.0 ?
131 kVolumeLevels :
132 std::max(1, int(std::ceil(level * (kVolumeLevels - 1)))));
133 if (image_index != image_index_) {
134 gfx::Rect region(0, image_index * kVolumeImageHeight,
135 kVolumeImageWidth, kVolumeImageHeight);
136 gfx::ImageSkia image_skia = gfx::ImageSkiaOperations::ExtractSubset(
137 *(image_.ToImageSkia()), region);
138 SetImage(views::CustomButton::STATE_NORMAL, &image_skia);
139 image_index_ = image_index;
140 }
141 SchedulePaint();
142 }
143
144 private:
145 // Overridden from views::View.
146 virtual gfx::Size GetPreferredSize() OVERRIDE {
147 gfx::Size size = views::ToggleImageButton::GetPreferredSize();
148 size.set_height(kTrayPopupItemHeight);
149 return size;
150 }
151
152 gfx::Image image_;
153 int image_index_;
154
155 DISALLOW_COPY_AND_ASSIGN(VolumeButton);
156 };
157
158 class VolumeSlider : public views::Slider {
159 public:
160 explicit VolumeSlider(views::SliderListener* listener)
161 : views::Slider(listener, views::Slider::HORIZONTAL) {
162 set_focus_border_color(kFocusBorderColor);
163 SetValue(GetVolumeLevel());
164 SetAccessibleName(
165 ui::ResourceBundle::GetSharedInstance().GetLocalizedString(
166 IDS_ASH_STATUS_TRAY_VOLUME));
167 Update();
168 }
169 virtual ~VolumeSlider() {}
170
171 void Update() {
172 UpdateState(!IsAudioMuted());
173 }
174
175 DISALLOW_COPY_AND_ASSIGN(VolumeSlider);
176 };
177
178 // Vertical bar separator that can be placed on the VolumeView.
179 class BarSeparator : public views::View {
180 public:
181 BarSeparator() {}
182 virtual ~BarSeparator() {}
183
184 // Overriden from views::View.
185 virtual gfx::Size GetPreferredSize() OVERRIDE {
186 return gfx::Size(kBarSeparatorWidth, kBarSeparatorHeight);
187 }
188
189 private:
190 virtual void OnPaint(gfx::Canvas* canvas) OVERRIDE {
191 canvas->FillRect(gfx::Rect(width() / 2, 0, 1, height()),
192 kButtonStrokeColor);
193 }
194
195 DISALLOW_COPY_AND_ASSIGN(BarSeparator);
196 };
197
198 class VolumeView : public ActionableView,
199 public views::ButtonListener,
200 public views::SliderListener {
201 public:
202 VolumeView(SystemTrayItem* owner, bool is_default_view)
203 : owner_(owner),
204 icon_(NULL),
205 slider_(NULL),
206 bar_(NULL),
207 device_type_(NULL),
208 more_(NULL),
209 is_default_view_(is_default_view) {
210 SetFocusable(false);
211 SetLayoutManager(new views::BoxLayout(views::BoxLayout::kHorizontal,
212 kTrayPopupPaddingHorizontal, 0, kTrayPopupPaddingBetweenItems));
213
214 icon_ = new VolumeButton(this);
215 AddChildView(icon_);
216
217 slider_ = new VolumeSlider(this);
218 AddChildView(slider_);
219
220 bar_ = new BarSeparator;
221 AddChildView(bar_);
222
223 device_type_ = new views::ImageView;
224 AddChildView(device_type_);
225
226 more_ = new views::ImageView;
227 more_->EnableCanvasFlippingForRTLUI(true);
228 more_->SetImage(ui::ResourceBundle::GetSharedInstance().GetImageNamed(
229 IDR_AURA_UBER_TRAY_MORE).ToImageSkia());
230 AddChildView(more_);
231
232 Update();
233 }
234
235 virtual ~VolumeView() {}
236
237 void Update() {
238 icon_->Update();
239 slider_->Update();
240 UpdateDeviceTypeAndMore();
241 Layout();
242 }
243
244 // Sets volume level on slider_, |percent| is ranged from [0.00] to [1.00].
245 void SetVolumeLevel(float percent) {
246 // Slider's value is in finer granularity than audio volume level(0.01),
247 // there will be a small discrepancy between slider's value and volume level
248 // on audio side. To avoid the jittering in slider UI, do not set change
249 // slider value if the change is less than 1%.
250 if (std::abs(percent-slider_->value()) < 0.01)
251 return;
252 // The change in volume will be reflected via accessibility system events,
253 // so we prevent the UI event from being sent here.
254 slider_->set_enable_accessibility_events(false);
255 slider_->SetValue(percent);
256 // It is possible that the volume was (un)muted, but the actual volume level
257 // did not change. In that case, setting the value of the slider won't
258 // trigger an update. So explicitly trigger an update.
259 Update();
260 slider_->set_enable_accessibility_events(true);
261 }
262
263 private:
264 // Updates bar_, device_type_ icon, and more_ buttons.
265 void UpdateDeviceTypeAndMore() {
266 if (!ash::switches::ShowAudioDeviceMenu() || !is_default_view_) {
267 more_->SetVisible(false);
268 bar_->SetVisible(false);
269 device_type_->SetVisible(false);
270 return;
271 }
272
273 CrasAudioHandler* audio_handler = CrasAudioHandler::Get();
274 bool show_more = audio_handler->has_alternative_output() ||
275 audio_handler->has_alternative_input();
276 more_->SetVisible(show_more);
277
278 // Show output device icon if necessary.
279 chromeos::AudioDevice device;
280 if (!audio_handler->GetActiveOutputDevice(&device))
281 return;
282 int device_icon = GetAudioDeviceIconId(device.type);
283 bar_->SetVisible(show_more);
284 if (device_icon != kNoAudioDeviceIcon) {
285 device_type_->SetVisible(true);
286 device_type_->SetImage(
287 ui::ResourceBundle::GetSharedInstance().GetImageNamed(
288 device_icon).ToImageSkia());
289 } else {
290 device_type_->SetVisible(false);
291 }
292 }
293
294 void HandleVolumeUp(int volume) {
295 CrasAudioHandler* audio_handler = CrasAudioHandler::Get();
296 audio_handler->SetOutputVolumePercent(volume);
297 if (audio_handler->IsOutputMuted() &&
298 !audio_handler->IsOutputVolumeBelowDefaultMuteLvel())
299 audio_handler->SetOutputMute(false);
300 }
301
302 void HandleVolumeDown(int volume) {
303 CrasAudioHandler* audio_handler = CrasAudioHandler::Get();
304 audio_handler->SetOutputVolumePercent(volume);
305 if (audio_handler->IsOutputVolumeBelowDefaultMuteLvel() &&
306 !audio_handler->IsOutputMuted()) {
307 audio_handler->SetOutputMute(true);
308 } else if (!audio_handler->IsOutputVolumeBelowDefaultMuteLvel() &&
309 audio_handler->IsOutputMuted()) {
310 audio_handler->SetOutputMute(false);
311 }
312 }
313
314 // Overridden from views::View.
315 virtual void Layout() OVERRIDE {
316 views::View::Layout();
317
318 if (!more_->visible()) {
319 int w = width() - slider_->bounds().x() -
320 kSliderRightPaddingToVolumeViewEdge;
321 slider_->SetSize(gfx::Size(w, slider_->height()));
322 return;
323 }
324
325 // Make sure the chevron always has the full size.
326 gfx::Size size = more_->GetPreferredSize();
327 gfx::Rect bounds(size);
328 bounds.set_x(width() - size.width() - kTrayPopupPaddingBetweenItems);
329 bounds.set_y((height() - size.height()) / 2);
330 more_->SetBoundsRect(bounds);
331
332 // Layout either bar_ or device_type_ at the left of the more_ button.
333 views::View* view_left_to_more;
334 if (device_type_->visible())
335 view_left_to_more = device_type_;
336 else
337 view_left_to_more = bar_;
338 gfx::Size view_size = view_left_to_more->GetPreferredSize();
339 gfx::Rect view_bounds(view_size);
340 view_bounds.set_x(more_->bounds().x() - view_size.width() -
341 kExtraPaddingBetweenBarAndMore);
342 view_bounds.set_y((height() - view_size.height()) / 2);
343 view_left_to_more->SetBoundsRect(view_bounds);
344
345 // Layout vertical bar next to view_left_to_more if device_type_ is visible.
346 if (device_type_->visible()) {
347 gfx::Size bar_size = bar_->GetPreferredSize();
348 gfx::Rect bar_bounds(bar_size);
349 bar_bounds.set_x(view_left_to_more->bounds().x() - bar_size.width());
350 bar_bounds.set_y((height() - bar_size.height()) / 2);
351 bar_->SetBoundsRect(bar_bounds);
352 }
353
354 // Layout slider, calculate slider width.
355 gfx::Rect slider_bounds = slider_->bounds();
356 slider_bounds.set_width(
357 bar_->bounds().x()
358 - (device_type_->visible() ? 0 : kTrayPopupPaddingBetweenItems)
359 - slider_bounds.x());
360 slider_->SetBoundsRect(slider_bounds);
361 }
362
363 // Overridden from views::ButtonListener.
364 virtual void ButtonPressed(views::Button* sender,
365 const ui::Event& event) OVERRIDE {
366 CHECK(sender == icon_);
367 bool mute_on = !IsAudioMuted();
368 CrasAudioHandler::Get()->SetOutputMute(mute_on);
369 if (!mute_on)
370 CrasAudioHandler::Get()->AdjustOutputVolumeToAudibleLevel();
371 }
372
373 // Overridden from views:SliderListener.
374 virtual void SliderValueChanged(views::Slider* sender,
375 float value,
376 float old_value,
377 views::SliderChangeReason reason) OVERRIDE {
378 if (reason == views::VALUE_CHANGED_BY_USER) {
379 int volume = value * 100.0f;
380 int old_volume = CrasAudioHandler::Get()->GetOutputVolumePercent();
381 // Do not call change audio volume if the difference is less than
382 // 1%, which is beyond cras audio api's granularity for output volume.
383 if (std::abs(volume - old_volume) < 1)
384 return;
385 Shell::GetInstance()->metrics()->RecordUserMetricsAction(
386 is_default_view_ ?
387 ash::UMA_STATUS_AREA_CHANGED_VOLUME_MENU :
388 ash::UMA_STATUS_AREA_CHANGED_VOLUME_POPUP);
389 if (volume > old_volume)
390 HandleVolumeUp(volume);
391 else
392 HandleVolumeDown(volume);
393 }
394 icon_->Update();
395 }
396
397 // Overriden from ActionableView.
398 virtual bool PerformAction(const ui::Event& event) OVERRIDE {
399 if (!more_->visible())
400 return false;
401 owner_->TransitionDetailedView();
402 return true;
403 }
404
405 SystemTrayItem* owner_;
406 VolumeButton* icon_;
407 VolumeSlider* slider_;
408 BarSeparator* bar_;
409 views::ImageView* device_type_;
410 views::ImageView* more_;
411 bool is_default_view_;
412
413 DISALLOW_COPY_AND_ASSIGN(VolumeView);
414 };
415
416 class AudioDetailedView : public TrayDetailsView,
417 public ViewClickListener {
418 public:
419 AudioDetailedView(SystemTrayItem* owner, user::LoginStatus login)
420 : TrayDetailsView(owner),
421 login_(login) {
422 CreateItems();
423 Update();
424 }
425
426 virtual ~AudioDetailedView() {
427 }
428
429 void Update() {
430 UpdateAudioDevices();
431 Layout();
432 }
433
434 private:
435 void CreateItems() {
436 CreateScrollableList();
437 CreateHeaderEntry();
438 }
439
440 void CreateHeaderEntry() {
441 CreateSpecialRow(IDS_ASH_STATUS_TRAY_AUDIO, this);
442 }
443
444 void UpdateAudioDevices() {
445 output_devices_.clear();
446 input_devices_.clear();
447 chromeos::AudioDeviceList devices;
448 CrasAudioHandler::Get()->GetAudioDevices(&devices);
449 for (size_t i = 0; i < devices.size(); ++i) {
450 if (devices[i].is_input)
451 input_devices_.push_back(devices[i]);
452 else
453 output_devices_.push_back(devices[i]);
454 }
455 UpdateScrollableList();
456 }
457
458 void UpdateScrollableList() {
459 scroll_content()->RemoveAllChildViews(true);
460 device_map_.clear();
461
462 // Add audio output devices.
463 AddScrollListInfoItem(
464 l10n_util::GetStringUTF16(IDS_ASH_STATUS_TRAY_AUDIO_OUTPUT));
465 for (size_t i = 0; i < output_devices_.size(); ++i) {
466 HoverHighlightView* container = AddScrollListItem(
467 GetAudioDeviceName(output_devices_[i]),
468 gfx::Font::NORMAL,
469 output_devices_[i].active); /* checkmark if active */
470 device_map_[container] = output_devices_[i];
471 }
472
473 AddScrollSeparator();
474
475 // Add audio input devices.
476 AddScrollListInfoItem(
477 l10n_util::GetStringUTF16(IDS_ASH_STATUS_TRAY_AUDIO_INPUT));
478 for (size_t i = 0; i < input_devices_.size(); ++i) {
479 HoverHighlightView* container = AddScrollListItem(
480 GetAudioDeviceName(input_devices_[i]),
481 gfx::Font::NORMAL,
482 input_devices_[i].active); /* checkmark if active */
483 device_map_[container] = input_devices_[i];
484 }
485
486 scroll_content()->SizeToPreferredSize();
487 scroller()->Layout();
488 }
489
490 void AddScrollListInfoItem(const base::string16& text) {
491 views::Label* label = new views::Label(
492 text,
493 ui::ResourceBundle::GetSharedInstance().GetFontList(
494 ui::ResourceBundle::BoldFont));
495
496 // Align info item with checkbox items
497 int margin = kTrayPopupPaddingHorizontal +
498 kTrayPopupDetailsLabelExtraLeftMargin;
499 int left_margin = 0;
500 int right_margin = 0;
501 if (base::i18n::IsRTL())
502 right_margin = margin;
503 else
504 left_margin = margin;
505
506 label->SetBorder(
507 views::Border::CreateEmptyBorder(ash::kTrayPopupPaddingBetweenItems,
508 left_margin,
509 ash::kTrayPopupPaddingBetweenItems,
510 right_margin));
511 label->SetHorizontalAlignment(gfx::ALIGN_LEFT);
512 label->SetEnabledColor(SkColorSetARGB(192, 0, 0, 0));
513
514 scroll_content()->AddChildView(label);
515 }
516
517 HoverHighlightView* AddScrollListItem(const base::string16& text,
518 gfx::Font::FontStyle style,
519 bool checked) {
520 HoverHighlightView* container = new HoverHighlightView(this);
521 container->AddCheckableLabel(text, style, checked);
522 scroll_content()->AddChildView(container);
523 return container;
524 }
525
526 // Overridden from ViewClickListener.
527 virtual void OnViewClicked(views::View* sender) OVERRIDE {
528 if (sender == footer()->content()) {
529 TransitionToDefaultView();
530 } else {
531 AudioDeviceMap::iterator iter = device_map_.find(sender);
532 if (iter == device_map_.end())
533 return;
534 chromeos::AudioDevice& device = iter->second;
535 CrasAudioHandler::Get()->SwitchToDevice(device);
536 }
537 }
538
539 typedef std::map<views::View*, chromeos::AudioDevice> AudioDeviceMap;
540
541 user::LoginStatus login_;
542 chromeos::AudioDeviceList output_devices_;
543 chromeos::AudioDeviceList input_devices_;
544 AudioDeviceMap device_map_;
545
546 DISALLOW_COPY_AND_ASSIGN(AudioDetailedView);
547 };
548
549 } // namespace tray
550
551 TrayAudio::TrayAudio(SystemTray* system_tray)
552 : TrayImageItem(system_tray, IDR_AURA_UBER_TRAY_VOLUME_MUTE),
553 volume_view_(NULL),
554 audio_detail_(NULL),
555 pop_up_volume_view_(false) {
556 CrasAudioHandler::Get()->AddAudioObserver(this);
557 }
558
559 TrayAudio::~TrayAudio() {
560 if (CrasAudioHandler::IsInitialized())
561 CrasAudioHandler::Get()->RemoveAudioObserver(this);
562 }
563
564 bool TrayAudio::GetInitialVisibility() {
565 return IsAudioMuted();
566 }
567
568 views::View* TrayAudio::CreateDefaultView(user::LoginStatus status) {
569 volume_view_ = new tray::VolumeView(this, true);
570 return volume_view_;
571 }
572
573 views::View* TrayAudio::CreateDetailedView(user::LoginStatus status) {
574 if (!ash::switches::ShowAudioDeviceMenu() || pop_up_volume_view_) {
575 volume_view_ = new tray::VolumeView(this, false);
576 return volume_view_;
577 } else {
578 Shell::GetInstance()->metrics()->RecordUserMetricsAction(
579 ash::UMA_STATUS_AREA_DETAILED_AUDIO_VIEW);
580 audio_detail_ = new tray::AudioDetailedView(this, status);
581 return audio_detail_;
582 }
583 }
584
585 void TrayAudio::DestroyDefaultView() {
586 volume_view_ = NULL;
587 }
588
589 void TrayAudio::DestroyDetailedView() {
590 if (audio_detail_) {
591 audio_detail_ = NULL;
592 } else if (volume_view_) {
593 volume_view_ = NULL;
594 pop_up_volume_view_ = false;
595 }
596 }
597
598 bool TrayAudio::ShouldHideArrow() const {
599 return true;
600 }
601
602 bool TrayAudio::ShouldShowShelf() const {
603 return ash::switches::ShowAudioDeviceMenu() && !pop_up_volume_view_;
604 }
605
606 void TrayAudio::OnOutputVolumeChanged() {
607 float percent = GetVolumeLevel();
608 if (tray_view())
609 tray_view()->SetVisible(GetInitialVisibility());
610
611 if (volume_view_) {
612 volume_view_->SetVolumeLevel(percent);
613 SetDetailedViewCloseDelay(kTrayPopupAutoCloseDelayInSeconds);
614 return;
615 }
616 pop_up_volume_view_ = true;
617 PopupDetailedView(kTrayPopupAutoCloseDelayInSeconds, false);
618 }
619
620 void TrayAudio::OnOutputMuteChanged() {
621 if (tray_view())
622 tray_view()->SetVisible(GetInitialVisibility());
623
624 if (volume_view_) {
625 volume_view_->Update();
626 SetDetailedViewCloseDelay(kTrayPopupAutoCloseDelayInSeconds);
627 } else {
628 pop_up_volume_view_ = true;
629 PopupDetailedView(kTrayPopupAutoCloseDelayInSeconds, false);
630 }
631 }
632
633 void TrayAudio::OnInputGainChanged() {
634 }
635
636 void TrayAudio::OnInputMuteChanged() {
637 }
638
639 void TrayAudio::OnAudioNodesChanged() {
640 Update();
641 }
642
643 void TrayAudio::OnActiveOutputNodeChanged() {
644 Update();
645 }
646
647 void TrayAudio::OnActiveInputNodeChanged() {
648 Update();
649 }
650
651 void TrayAudio::Update() {
652 if (tray_view())
653 tray_view()->SetVisible(GetInitialVisibility());
654 if (audio_detail_)
655 audio_detail_->Update();
656 if (volume_view_) {
657 volume_view_->SetVolumeLevel(GetVolumeLevel());
658 volume_view_->Update();
659 }
660 }
661
662 } // namespace internal
663 } // namespace ash
OLDNEW
« no previous file with comments | « ash/system/chromeos/audio/tray_audio.h ('k') | ash/system/chromeos/audio/tray_audio_chromeos.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698