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

Unified Diff: chrome/browser/media/media_stream_capture_indicator.cc

Issue 10168008: Show camera and microphone status indicators. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: removed debugging code. Created 8 years, 8 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 side-by-side diff with in-line comments
Download patch
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();
+}

Powered by Google App Engine
This is Rietveld 408576698