OLD | NEW |
---|---|
(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 } | |
OLD | NEW |