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

Side by Side 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: addressed Tommi's comments. Created 8 years, 7 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 | Annotate | Revision Log
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 "chrome/browser/media/media_stream_capture_indicator.h"
6
7 #include "base/utf_string_conversions.h"
8 #include "chrome/app/chrome_command_ids.h"
9 #include "chrome/browser/browser_process.h"
10 #include "chrome/browser/browser_shutdown.h"
11 #include "chrome/browser/status_icons/status_icon.h"
12 #include "chrome/browser/status_icons/status_tray.h"
13 #include "content/public/browser/browser_thread.h"
14 #include "grit/chromium_strings.h"
15 #include "grit/generated_resources.h"
16 #include "grit/theme_resources.h"
17 #include "ui/base/l10n/l10n_util.h"
18 #include "ui/base/resource/resource_bundle.h"
19
20 using content::BrowserThread;
21
22 MediaStreamCaptureIndicator::MediaStreamCaptureIndicator()
23 : status_icon_(NULL) {}
24
25 MediaStreamCaptureIndicator::~MediaStreamCaptureIndicator() {
26 Hide();
27 }
28
29 bool MediaStreamCaptureIndicator::IsCommandIdChecked(
30 int command_id) const {
31 NOTIMPLEMENTED() << "There are no checked items in the MediaStream menu.";
32 return false;
33 }
34
35 bool MediaStreamCaptureIndicator::IsCommandIdEnabled(
36 int command_id) const {
37 return command_id != IDC_MinimumLabelValue;
38 }
39
40 bool MediaStreamCaptureIndicator::GetAcceleratorForCommandId(
41 int command_id, ui::Accelerator* accelerator) {
42 // No accelerators for status icon context menu.
43 return false;
44 }
45
46 void MediaStreamCaptureIndicator::ExecuteCommand(int command_id) {
47 // TODO(xians) : Implement all the following execute command function.
48 switch (command_id) {
49 case IDC_MEDIA_STREAM_DEVICE_STATUS_TRAY:
50 break;
51 case IDC_MEDIA_CONTEXT_MEDIA_STREAM_CAPTURE_AUDIO:
52 break;
53 case IDC_MEDIA_CONTEXT_MEDIA_STREAM_CAPTURE_VIDEO:
54 break;
55 case IDC_EXIT:
56 Hide();
57 break;
58 default:
59 NOTREACHED();
60 break;
61 }
62 }
63
64 void MediaStreamCaptureIndicator::OnCaptureDevicesOpened(
65 const std::string& url,
66 const content::MediaStreamDevices& devices) {
67 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
68 DCHECK(!url.empty());
69 DCHECK(!devices.empty());
70 if (!g_browser_process)
71 return;
72
73 CreateStatusTray();
74
75 // If we don't have a status icon or one could not be created successfully,
76 // then no need to continue.
77 if (!status_icon_)
78 return;
79
80 AddCaptureDeviceUser(url, devices);
81
82 ShowBalloon(url, devices);
83 }
84
85 void MediaStreamCaptureIndicator::OnCaptureDevicesClosed(
86 const std::string& url,
87 const content::MediaStreamDevices& devices) {
88 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
89 DCHECK(!url.empty());
90 DCHECK(!devices.empty());
91 if (!g_browser_process)
92 return;
93
94 if (!status_icon_)
95 return;
96
97 DCHECK(!users_.empty());
98 RemoveCaptureDeviceUser(url, devices);
99
100 if (users_.empty())
101 Hide();
102 }
103
104 void MediaStreamCaptureIndicator::CreateStatusTray() {
105 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
MAD 2012/04/25 15:34:53 Nit: You already DCHECKed on that in the caller me
no longer working on chromium 2012/04/30 09:59:38 Done.
106 if (status_icon_)
107 return;
108
109 StatusTray* status_tray = g_browser_process->status_tray();
110 if (!status_tray) {
111 LOG(WARNING) << "This platform doesn't support notification icons";
MAD 2012/04/25 15:34:53 VLOG maybe? Or do you really want this LOG to alwa
Nico 2012/04/25 15:52:51 No log needed at all
no longer working on chromium 2012/04/30 09:59:38 Done.
no longer working on chromium 2012/04/30 09:59:38 Done.
112 return;
113 }
114
115 status_icon_ = status_tray->CreateStatusIcon();
116
117 status_icon_->SetToolTip(l10n_util::GetStringUTF16(
118 IDS_MEDIA_STREAM_STATUS_TRAY_TOOLTIP));
119
120 EnsureStatusTrayIcon();
121 DCHECK(!icon_image_.empty());
122
123 status_icon_->SetImage(icon_image_);
124 }
125
126 void MediaStreamCaptureIndicator::EnsureStatusTrayIcon() {
127 if (icon_image_.empty()) {
128 icon_image_ = *ResourceBundle::GetSharedInstance().GetBitmapNamed(
129 IDR_MEDIA_STREAM_CAPTURE_LED);
130 }
131 }
132
133 void MediaStreamCaptureIndicator::ShowBalloon(
134 const std::string& url,
135 const content::MediaStreamDevices& devices) {
136 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
MAD 2012/04/25 15:34:53 Nit: Again, not needed...
no longer working on chromium 2012/04/30 09:59:38 Done.
137 DCHECK(status_icon_);
138 DCHECK(!icon_image_.empty());
139
140 string16 title = l10n_util::GetStringUTF16(
141 IDS_MEDIA_STREAM_STATUS_TRAY_BALLOON_TITLE);
142
143 string16 message= l10n_util::GetStringFUTF16(
MAD 2012/04/25 15:34:53 message= -> message =
no longer working on chromium 2012/04/30 09:59:38 Done.
144 IDS_MEDIA_STREAM_STATUS_TRAY_BALLOON_BODY, ASCIIToUTF16(url));
145
146 status_icon_->DisplayBalloon(icon_image_, title, message);
147 }
148
149 void MediaStreamCaptureIndicator::Hide() {
150 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
151 if (!status_icon_)
152 return;
153
154 // If there is no browser process, we should not do anything.
155 if (!g_browser_process)
156 return;
157
158 StatusTray* status_tray = g_browser_process->status_tray();
159 if (status_tray != NULL) {
160 status_tray->RemoveStatusIcon(status_icon_);
161 status_icon_ = NULL;
162 }
163 }
164
165 void MediaStreamCaptureIndicator::UpdateStatusTrayIconContextMenu() {
166 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
167 DCHECK(status_icon_);
168 DCHECK(!users_.empty());
169
170 ui::SimpleMenuModel* menu = new ui::SimpleMenuModel(this);
171 // TODO(xians): Do we need a About MediaStream item for the menu?
172 menu->AddItem(IDC_MEDIA_STREAM_DEVICE_STATUS_TRAY,
173 l10n_util::GetStringUTF16(IDS_MEDIA_STREAM_STATUS_TRAY_TITLE));
174 menu->AddSeparator();
175
176 for (CaptureDeviceUserList::const_iterator iter = users_.begin();
177 iter != users_.end(); ++iter) {
178 int command_id = IDC_MEDIA_CONTEXT_MEDIA_STREAM_CAPTURE_AUDIO;
179 int message_id = IDS_MEDIA_STREAM_STATUS_TRAY_ITEM_AUDIO;
180 if (iter->type == content::MEDIA_STREAM_DEVICE_TYPE_VIDEO_CAPTURE) {
181 command_id = IDC_MEDIA_CONTEXT_MEDIA_STREAM_CAPTURE_VIDEO;
182 message_id = IDS_MEDIA_STREAM_STATUS_TRAY_ITEM_VIDEO;
183 }
184 string16 message = l10n_util::GetStringFUTF16(message_id,
185 ASCIIToUTF16(iter->host),
186 ASCIIToUTF16(iter->device));
187 menu->AddItem(command_id, message);
188 }
189
190 menu->AddSeparator();
191 menu->AddItem(IDC_EXIT, l10n_util::GetStringUTF16(IDS_EXIT));
192
193 // The icon will take the ownership of the passed context menu.
MAD 2012/04/25 15:34:53 I would still use a scoped_ptr<> in case a return
no longer working on chromium 2012/04/30 09:59:38 Done.
194 status_icon_->SetContextMenu(menu);
195 }
196
197 void MediaStreamCaptureIndicator::AddCaptureDeviceUser(
198 const std::string& url, const content::MediaStreamDevices& devices) {
199 for (content::MediaStreamDevices::const_iterator dev = devices.begin();
200 dev != devices.end(); ++dev) {
MAD 2012/04/25 15:34:53 Nit: consistency, above you align to 4 columns, an
no longer working on chromium 2012/04/30 09:59:38 Done.
201 DCHECK(dev->type == content::MEDIA_STREAM_DEVICE_TYPE_AUDIO_CAPTURE ||
202 dev->type == content::MEDIA_STREAM_DEVICE_TYPE_VIDEO_CAPTURE);
203 users_.push_back(CaptureDeviceUser(url, dev->name, dev->type));
204 }
205
206 UpdateStatusTrayIconContextMenu();
207 }
208
209 void MediaStreamCaptureIndicator::RemoveCaptureDeviceUser(
210 const std::string& url, const content::MediaStreamDevices& devices) {
211 for (content::MediaStreamDevices::const_iterator dev = devices.begin();
212 dev != devices.end(); ++dev) {
213 CaptureDeviceUserList::iterator iter = users_.begin();
214 while (iter != users_.end()) {
215 if (url == iter->host &&
216 dev->name == iter->device &&
217 dev->type == iter->type) {
218 break;
219 }
220 ++iter;
221 }
222 if (iter != users_.end()) {
223 users_.erase(iter);
224 } else {
225 DLOG(ERROR) << "Failed to find Media Stream host " << url
226 << " for device " << dev->name
227 << " with type " << dev->type;
228 }
229 }
230
231 if (!users_.empty())
MAD 2012/04/25 15:34:53 Don't you want to clear the context menu when user
no longer working on chromium 2012/04/30 09:59:38 If users_ is empty, we will call Hide() to destroy
232 UpdateStatusTrayIconContextMenu();
233 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698