Index: chrome/browser/media/media_stream_capture_indicator.cc |
diff --git a/chrome/browser/media/media_stream_capture_indicator.cc b/chrome/browser/media/media_stream_capture_indicator.cc |
new file mode 100644 |
index 0000000000000000000000000000000000000000..f68d6894a6306163c7e01bebfee7c5386b55763a |
--- /dev/null |
+++ b/chrome/browser/media/media_stream_capture_indicator.cc |
@@ -0,0 +1,233 @@ |
+// Copyright (c) 2012 The Chromium Authors. All rights reserved. |
+// Use of this source code is governed by a BSD-style license that can be |
+// found in the LICENSE file. |
+ |
+#include "chrome/browser/media/media_stream_capture_indicator.h" |
+ |
+#include "base/utf_string_conversions.h" |
+#include "chrome/app/chrome_command_ids.h" |
+#include "chrome/browser/browser_process.h" |
+#include "chrome/browser/browser_shutdown.h" |
+#include "chrome/browser/status_icons/status_icon.h" |
+#include "chrome/browser/status_icons/status_tray.h" |
+#include "content/public/browser/browser_thread.h" |
+#include "grit/chromium_strings.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" |
+ |
+using content::BrowserThread; |
+ |
+MediaStreamCaptureIndicator::MediaStreamCaptureIndicator() |
+ : status_icon_(NULL) { |
+ // We should not start up if there is no browser process or if we are |
+ // currently quitting. |
+ if (!g_browser_process || browser_shutdown::IsTryingToQuit()) |
+ return; |
tommi (sloooow) - chröme
2012/04/24 11:36:18
uhm... this doesn't make any sense :)
no longer working on chromium
2012/04/25 13:52:51
Done.
|
+} |
+ |
+MediaStreamCaptureIndicator::~MediaStreamCaptureIndicator() { |
+ Hide(); |
+} |
+ |
+bool MediaStreamCaptureIndicator::IsCommandIdChecked( |
+ int command_id) const { |
+ NOTIMPLEMENTED() << "There are no checked items in the MediaStream menu."; |
+ return false; |
+} |
+ |
+bool MediaStreamCaptureIndicator::IsCommandIdEnabled( |
+ int command_id) const { |
+ return command_id != IDC_MinimumLabelValue; |
+} |
+ |
+bool MediaStreamCaptureIndicator::GetAcceleratorForCommandId( |
+ int command_id, ui::Accelerator* accelerator) { |
+ // No accelerators for status icon context menu. |
+ return false; |
+} |
+ |
+void MediaStreamCaptureIndicator::ExecuteCommand(int command_id) { |
+ // TODO(xians) : Implement all the following execute command function. |
+ switch (command_id) { |
+ case IDC_MEDIA_STREAM_DEVICE_STATUS_TRAY: |
+ break; |
+ case IDC_MEDIA_CONTEXT_MEDIA_STREAM_CAPTURE_AUDIO: |
+ break; |
+ case IDC_MEDIA_CONTEXT_MEDIA_STREAM_CAPTURE_VIDEO: |
+ break; |
+ case IDC_EXIT: |
+ Hide(); |
+ break; |
+ default: |
+ break; |
tommi (sloooow) - chröme
2012/04/24 11:36:18
NOTREACHED()? or at least DLOG(ERROR)?
no longer working on chromium
2012/04/25 13:52:51
Done.
|
+ } |
+} |
+ |
+void MediaStreamCaptureIndicator::OnCaptureDevicesOpened( |
+ const std::string& url, |
+ const content::MediaStreamDevices& devices) { |
+ DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
+ DCHECK(!url.empty() && !devices.empty()); |
tommi (sloooow) - chröme
2012/04/24 11:36:18
nit: separate DCHECKs so that it's clear which one
no longer working on chromium
2012/04/25 13:52:51
Done.
|
+ if (!g_browser_process) |
+ return; |
+ |
+ CreateStatusTray(); |
+ |
+ // If we don't have a status icon or one could not be created successfully, |
+ // then no need to continue. |
+ if (!status_icon_) |
+ return; |
+ |
+ AddCaptureDeviceUser(url, devices); |
+ |
+ ShowBalloon(url, devices); |
+} |
+ |
+void MediaStreamCaptureIndicator::OnCaptureDevicesClosed( |
+ const std::string& url, |
+ const content::MediaStreamDevices& devices) { |
+ DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
+ DCHECK(!url.empty() && !devices.empty()); |
tommi (sloooow) - chröme
2012/04/24 11:36:18
separate dchecks
no longer working on chromium
2012/04/25 13:52:51
Done.
|
+ if (!g_browser_process) |
+ return; |
+ |
+ if (!status_icon_) |
+ return; |
+ |
+ DCHECK(!users_.empty()); |
+ RemoveCaptureDeviceUser(url, devices); |
+ |
+ if (users_.empty()) |
+ Hide(); |
+} |
+ |
+void MediaStreamCaptureIndicator::CreateStatusTray() { |
+ DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
+ if (status_icon_) |
+ return; |
+ |
+ StatusTray* status_tray = g_browser_process->status_tray(); |
+ if (!status_tray) { |
+ LOG(WARNING) << "This platform doesn't support notification icons"; |
+ return; |
+ } |
+ |
+ status_icon_ = status_tray->CreateStatusIcon(); |
+ DCHECK(status_icon_); |
tommi (sloooow) - chröme
2012/04/24 11:36:18
this DCHECK isn't necessary since you deref the po
no longer working on chromium
2012/04/25 13:52:51
Done.
|
+ |
+ status_icon_->SetToolTip(l10n_util::GetStringUTF16( |
+ IDS_MEDIA_STREAM_STATUS_TRAY_TOOLTIP)); |
+ |
+ EnsureStatusTrayIcon(); |
+ DCHECK(!icon_image_.empty()); |
+ |
+ status_icon_->SetImage(icon_image_); |
+} |
+ |
+void MediaStreamCaptureIndicator::EnsureStatusTrayIcon() { |
+ if (icon_image_.empty()) { |
+ icon_image_ = *ResourceBundle::GetSharedInstance().GetBitmapNamed( |
+ IDR_MEDIA_STREAM_CAPTURE_LED); |
+ } |
+} |
+ |
+void MediaStreamCaptureIndicator::ShowBalloon( |
+ const std::string& url, |
+ const content::MediaStreamDevices& devices) { |
+ DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
+ DCHECK(status_icon_); |
+ DCHECK(!icon_image_.empty()); |
+ |
+ string16 title = l10n_util::GetStringUTF16( |
+ IDS_MEDIA_STREAM_STATUS_TRAY_BALLOON_TITLE); |
+ |
+ string16 message= l10n_util::GetStringFUTF16( |
+ IDS_MEDIA_STREAM_STATUS_TRAY_BALLOON_BODY, ASCIIToUTF16(url)); |
+ |
+ status_icon_->DisplayBalloon(icon_image_, title, message); |
+} |
+ |
+void MediaStreamCaptureIndicator::Hide() { |
+ DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
+ if (!status_icon_) |
+ return; |
+ |
+ // If there is no browser process, we should not do anything. |
+ if (!g_browser_process) |
+ return; |
+ |
+ StatusTray* status_tray = g_browser_process->status_tray(); |
+ if (status_tray != NULL) { |
+ status_tray->RemoveStatusIcon(status_icon_); |
+ status_icon_ = NULL; |
+ } |
+} |
+ |
+void MediaStreamCaptureIndicator::UpdateStatusTrayIconContextMenu() { |
+ DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
+ DCHECK(status_icon_); |
+ DCHECK(!users_.empty()); |
+ |
+ ui::SimpleMenuModel* menu = new ui::SimpleMenuModel(this); |
+ // TODO(xians): Do we need a About MediaStream item for the menu? |
+ menu->AddItem(IDC_MEDIA_STREAM_DEVICE_STATUS_TRAY, |
+ l10n_util::GetStringUTF16(IDS_MEDIA_STREAM_STATUS_TRAY_TITLE)); |
+ menu->AddSeparator(); |
+ |
+ for (CaptureDeviceUserList::const_iterator iter = users_.begin(); |
+ iter != users_.end(); ++iter) { |
+ int command_id = IDC_MEDIA_CONTEXT_MEDIA_STREAM_CAPTURE_AUDIO; |
+ int message_id = IDS_MEDIA_STREAM_STATUS_TRAY_ITEM_AUDIO; |
+ if (iter->type == content::MEDIA_STREAM_DEVICE_TYPE_VIDEO_CAPTURE) { |
+ command_id = IDC_MEDIA_CONTEXT_MEDIA_STREAM_CAPTURE_VIDEO; |
+ message_id = IDS_MEDIA_STREAM_STATUS_TRAY_ITEM_VIDEO; |
+ } |
+ string16 message = l10n_util::GetStringFUTF16(message_id, |
+ ASCIIToUTF16(iter->url), |
+ ASCIIToUTF16(iter->device)); |
+ menu->AddItem(command_id, message); |
+ } |
+ |
+ menu->AddSeparator(); |
+ menu->AddItem(IDC_EXIT, l10n_util::GetStringUTF16(IDS_EXIT)); |
+ |
+ status_icon_->SetContextMenu(menu); |
+} |
+ |
+void MediaStreamCaptureIndicator::AddCaptureDeviceUser( |
+ const std::string& url, const content::MediaStreamDevices& devices) { |
+ for (content::MediaStreamDevices::const_iterator dev = devices.begin(); |
+ dev != devices.end(); ++dev) { |
+ DCHECK(dev->type == content::MEDIA_STREAM_DEVICE_TYPE_AUDIO_CAPTURE || |
+ dev->type == content::MEDIA_STREAM_DEVICE_TYPE_VIDEO_CAPTURE); |
+ users_.push_back(CaptureDeviceUser(url, dev->name, dev->type)); |
+ } |
+ |
+ UpdateStatusTrayIconContextMenu(); |
+} |
+ |
+void MediaStreamCaptureIndicator::RemoveCaptureDeviceUser( |
+ const std::string& url, const content::MediaStreamDevices& devices) { |
+ for (content::MediaStreamDevices::const_iterator dev = devices.begin(); |
+ dev != devices.end(); ++dev) { |
+ CaptureDeviceUserList::iterator iter = users_.begin(); |
+ while (iter != users_.end()) { |
+ if (url == iter->url && |
+ dev->name == iter->device && |
+ dev->type == iter->type) { |
+ users_.erase(iter); |
+ break; |
+ } |
+ } |
+ if (iter == users_.end()) { |
+ DLOG(ERROR) << "Failed to find Media Stream user " << url |
+ << " for device " << dev->name |
+ << " with type " << dev->type; |
+ } |
+ } |
+ |
+ if (!users_.empty()) |
+ UpdateStatusTrayIconContextMenu(); |
+} |