OLD | NEW |
---|---|
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "chrome/browser/media/media_stream_capture_indicator.h" | 5 #include "chrome/browser/media/media_stream_capture_indicator.h" |
6 | 6 |
7 #include "base/bind.h" | 7 #include "base/bind.h" |
8 #include "base/i18n/rtl.h" | 8 #include "base/i18n/rtl.h" |
9 #include "base/utf_string_conversions.h" | 9 #include "base/utf_string_conversions.h" |
10 #include "chrome/app/chrome_command_ids.h" | 10 #include "chrome/app/chrome_command_ids.h" |
11 #include "chrome/browser/browser_process.h" | 11 #include "chrome/browser/browser_process.h" |
12 #include "chrome/browser/extensions/extension_service.h" | |
13 #include "chrome/browser/profiles/profile.h" | |
12 #include "chrome/browser/status_icons/status_icon.h" | 14 #include "chrome/browser/status_icons/status_icon.h" |
13 #include "chrome/browser/status_icons/status_tray.h" | 15 #include "chrome/browser/status_icons/status_tray.h" |
14 #include "chrome/browser/tab_contents/tab_util.h" | 16 #include "chrome/browser/tab_contents/tab_util.h" |
15 #include "content/public/browser/browser_thread.h" | 17 #include "content/public/browser/browser_thread.h" |
16 #include "content/public/browser/content_browser_client.h" | 18 #include "content/public/browser/content_browser_client.h" |
17 #include "content/public/browser/render_view_host.h" | 19 #include "content/public/browser/render_view_host.h" |
18 #include "content/public/browser/web_contents.h" | 20 #include "content/public/browser/web_contents.h" |
19 #include "content/public/browser/web_contents_delegate.h" | 21 #include "content/public/browser/web_contents_delegate.h" |
20 #include "grit/chromium_strings.h" | 22 #include "grit/chromium_strings.h" |
21 #include "grit/generated_resources.h" | 23 #include "grit/generated_resources.h" |
22 #include "grit/theme_resources.h" | 24 #include "grit/theme_resources.h" |
23 #include "net/base/net_util.h" | 25 #include "net/base/net_util.h" |
24 #include "ui/base/l10n/l10n_util.h" | 26 #include "ui/base/l10n/l10n_util.h" |
25 #include "ui/base/resource/resource_bundle.h" | 27 #include "ui/base/resource/resource_bundle.h" |
26 | 28 |
27 using content::BrowserThread; | 29 using content::BrowserThread; |
28 using content::WebContents; | 30 using content::WebContents; |
29 | 31 |
32 namespace { | |
33 | |
34 const extensions::Extension* GetExtension(int render_process_id, | |
35 int render_view_id) { | |
36 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | |
37 | |
38 WebContents* web_contents = tab_util::GetWebContentsByID( | |
39 render_process_id, render_view_id); | |
40 if (!web_contents) | |
41 return NULL; | |
42 | |
43 Profile* profile = | |
44 Profile::FromBrowserContext(web_contents->GetBrowserContext()); | |
45 if (!profile) | |
46 return NULL; | |
47 | |
48 ExtensionService* extensions = profile->GetExtensionService(); | |
Mihai Parparita -not on Chrome
2012/08/01 05:12:37
Nit: can you call this extensions_service, so that
Evan Stade
2012/08/07 02:18:32
Done.
| |
49 if (!extensions) | |
50 return NULL; | |
51 | |
52 return extensions->extensions()->GetExtensionOrAppByURL( | |
53 ExtensionURLInfo(web_contents->GetURL())); | |
54 } | |
55 | |
56 // Gets the security originator of the tab. It returns a string with no '/' | |
57 // at the end to display in the UI. | |
58 string16 GetSecurityOrigin(int render_process_id, int render_view_id) { | |
59 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | |
60 WebContents* tab_content = tab_util::GetWebContentsByID( | |
61 render_process_id, render_view_id); | |
62 if (!tab_content) | |
63 return string16(); | |
64 | |
65 std::string security_origin = tab_content->GetURL().GetOrigin().spec(); | |
66 | |
67 // Remove the last character if it is a '/'. | |
68 if (!security_origin.empty()) { | |
69 std::string::iterator it = security_origin.end() - 1; | |
70 if (*it == '/') | |
71 security_origin.erase(it); | |
72 } | |
73 | |
74 return UTF8ToUTF16(security_origin); | |
75 } | |
76 | |
77 string16 GetTitle(int render_process_id, int render_view_id) { | |
78 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | |
79 | |
80 const extensions::Extension* extension = | |
81 GetExtension(render_process_id, render_view_id); | |
82 if (extension) | |
83 return UTF8ToUTF16(extension->name()); | |
84 | |
85 WebContents* tab_content = tab_util::GetWebContentsByID( | |
86 render_process_id, render_view_id); | |
87 if (!tab_content) | |
88 return string16(); | |
89 | |
90 string16 tab_title = tab_content->GetTitle(); | |
91 | |
92 if (tab_title.empty()) { | |
93 // If the page's title is empty use its security originator. | |
94 tab_title = GetSecurityOrigin(render_process_id, render_view_id); | |
95 } else { | |
96 // If the page's title matches its URL, use its security originator. | |
97 std::string languages = | |
98 content::GetContentClient()->browser()->GetAcceptLangs( | |
99 tab_content->GetBrowserContext()); | |
100 if (tab_title == net::FormatUrl(tab_content->GetURL(), languages)) | |
101 tab_title = GetSecurityOrigin(render_process_id, render_view_id); | |
102 } | |
103 | |
104 return tab_title; | |
105 } | |
106 | |
107 } // namespace | |
108 | |
30 MediaStreamCaptureIndicator::TabEquals::TabEquals(int render_process_id, | 109 MediaStreamCaptureIndicator::TabEquals::TabEquals(int render_process_id, |
31 int render_view_id) | 110 int render_view_id) |
32 : render_process_id_(render_process_id), | 111 : render_process_id_(render_process_id), |
33 render_view_id_(render_view_id) {} | 112 render_view_id_(render_view_id) {} |
34 | 113 |
35 bool MediaStreamCaptureIndicator::TabEquals::operator() ( | 114 bool MediaStreamCaptureIndicator::TabEquals::operator() ( |
36 const MediaStreamCaptureIndicator::CaptureDeviceTab& tab) { | 115 const MediaStreamCaptureIndicator::CaptureDeviceTab& tab) { |
37 return (render_process_id_ == tab.render_process_id && | 116 return (render_process_id_ == tab.render_process_id && |
38 render_view_id_ == tab.render_view_id); | 117 render_view_id_ == tab.render_view_id); |
39 } | 118 } |
40 | 119 |
41 MediaStreamCaptureIndicator::MediaStreamCaptureIndicator() | 120 MediaStreamCaptureIndicator::MediaStreamCaptureIndicator() |
42 : status_icon_(NULL), | 121 : status_icon_(NULL), |
43 mic_image_(NULL), | 122 mic_image_(NULL), |
44 camera_image_(NULL), | 123 camera_image_(NULL), |
45 balloon_image_(NULL) { | 124 balloon_image_(NULL), |
125 ALLOW_THIS_IN_INITIALIZER_LIST(tracker_(this)) { | |
46 } | 126 } |
47 | 127 |
48 MediaStreamCaptureIndicator::~MediaStreamCaptureIndicator() { | 128 MediaStreamCaptureIndicator::~MediaStreamCaptureIndicator() { |
49 // The user is responsible for cleaning up by closing all the opened devices. | 129 // The user is responsible for cleaning up by closing all the opened devices. |
50 DCHECK(tabs_.empty()); | 130 DCHECK(tabs_.empty()); |
51 } | 131 } |
52 | 132 |
53 bool MediaStreamCaptureIndicator::IsCommandIdChecked( | 133 bool MediaStreamCaptureIndicator::IsCommandIdChecked( |
54 int command_id) const { | 134 int command_id) const { |
55 NOTIMPLEMENTED() << "There are no checked items in the MediaStream menu."; | 135 NOTIMPLEMENTED() << "There are no checked items in the MediaStream menu."; |
(...skipping 115 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
171 } | 251 } |
172 DCHECK(mic_image_); | 252 DCHECK(mic_image_); |
173 DCHECK(camera_image_); | 253 DCHECK(camera_image_); |
174 DCHECK(balloon_image_); | 254 DCHECK(balloon_image_); |
175 } | 255 } |
176 | 256 |
177 void MediaStreamCaptureIndicator::ShowBalloon( | 257 void MediaStreamCaptureIndicator::ShowBalloon( |
178 int render_process_id, | 258 int render_process_id, |
179 int render_view_id, | 259 int render_view_id, |
180 bool audio, | 260 bool audio, |
181 bool video) const { | 261 bool video) { |
182 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 262 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
183 DCHECK(audio || video); | 263 DCHECK(audio || video); |
184 string16 title = l10n_util::GetStringUTF16(IDS_PRODUCT_NAME); | |
185 | 264 |
186 int message_id = IDS_MEDIA_STREAM_STATUS_TRAY_BALLOON_BODY_AUDIO_AND_VIDEO; | 265 int message_id = IDS_MEDIA_STREAM_STATUS_TRAY_BALLOON_BODY_AUDIO_AND_VIDEO; |
187 if (audio && !video) | 266 if (audio && !video) |
188 message_id = IDS_MEDIA_STREAM_STATUS_TRAY_BALLOON_BODY_AUDIO_ONLY; | 267 message_id = IDS_MEDIA_STREAM_STATUS_TRAY_BALLOON_BODY_AUDIO_ONLY; |
189 else if (!audio && video) | 268 else if (!audio && video) |
190 message_id = IDS_MEDIA_STREAM_STATUS_TRAY_BALLOON_BODY_VIDEO_ONLY; | 269 message_id = IDS_MEDIA_STREAM_STATUS_TRAY_BALLOON_BODY_VIDEO_ONLY; |
191 | 270 |
192 string16 body = l10n_util::GetStringFUTF16( | 271 const extensions::Extension* extension = |
193 message_id, GetSecurityOrigin(render_process_id, render_view_id)); | 272 GetExtension(render_process_id, render_view_id); |
273 if (extension) { | |
274 pending_messages_.push_back( | |
275 l10n_util::GetStringFUTF16(message_id, | |
276 UTF8ToUTF16(extension->name()))); | |
277 tracker_.LoadImage( | |
278 extension, | |
279 extension->GetIconResource(32, ExtensionIconSet::MATCH_BIGGER), | |
280 gfx::Size(32, 32), | |
281 ImageLoadingTracker::CACHE); | |
282 return; | |
283 } | |
194 | 284 |
285 string16 title = l10n_util::GetStringUTF16(IDS_PRODUCT_NAME); | |
286 string16 body = l10n_util::GetStringFUTF16(message_id, | |
287 GetSecurityOrigin(render_process_id, render_view_id)); | |
195 status_icon_->DisplayBalloon(*balloon_image_, title, body); | 288 status_icon_->DisplayBalloon(*balloon_image_, title, body); |
196 } | 289 } |
197 | 290 |
291 void MediaStreamCaptureIndicator::OnImageLoaded( | |
292 const gfx::Image& image, | |
293 const std::string& extension_id, | |
294 int index) { | |
295 string16 message; | |
296 message.swap(pending_messages_[index]); | |
Evan Stade
2012/07/31 23:19:29
this leaks... the vector never gets smaller. But i
scherkus (not reviewing)
2012/08/01 00:18:17
I'm not super familiar with ImageLoadingTracker bu
no longer working on chromium
2012/08/01 07:54:14
should we just use erase to completely delete the
Evan Stade
2012/08/01 22:25:15
erase will move the rest of the elements in the ve
scherkus (not reviewing)
2012/08/01 22:40:08
I was thinking ImageLoadingTracker::Observer could
| |
297 | |
298 status_icon_->DisplayBalloon( | |
299 !image.IsEmpty() ? *image.ToImageSkia() : | |
300 *ResourceBundle::GetSharedInstance().GetImageSkiaNamed( | |
301 IDR_APP_DEFAULT_ICON), | |
302 string16(), | |
303 message); | |
304 } | |
305 | |
198 void MediaStreamCaptureIndicator::Hide() { | 306 void MediaStreamCaptureIndicator::Hide() { |
199 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 307 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
200 if (!status_icon_) | 308 if (!status_icon_) |
201 return; | 309 return; |
202 | 310 |
203 // If there is no browser process, we should not do anything. | 311 // If there is no browser process, we should not do anything. |
204 if (!g_browser_process) | 312 if (!g_browser_process) |
205 return; | 313 return; |
206 | 314 |
207 StatusTray* status_tray = g_browser_process->status_tray(); | 315 StatusTray* status_tray = g_browser_process->status_tray(); |
(...skipping 120 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
328 // Remove the tab if all the devices have been closed. | 436 // Remove the tab if all the devices have been closed. |
329 if (iter->audio_ref_count == 0 && iter->video_ref_count == 0) | 437 if (iter->audio_ref_count == 0 && iter->video_ref_count == 0) |
330 tabs_.erase(iter); | 438 tabs_.erase(iter); |
331 | 439 |
332 if (tabs_.empty()) | 440 if (tabs_.empty()) |
333 Hide(); | 441 Hide(); |
334 else | 442 else |
335 UpdateStatusTrayIconContextMenu(); | 443 UpdateStatusTrayIconContextMenu(); |
336 } | 444 } |
337 | 445 |
338 string16 MediaStreamCaptureIndicator::GetTitle(int render_process_id, | |
339 int render_view_id) const { | |
340 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | |
341 WebContents* tab_content = tab_util::GetWebContentsByID( | |
342 render_process_id, render_view_id); | |
343 if (!tab_content) | |
344 return string16(); | |
345 | |
346 string16 tab_title = tab_content->GetTitle(); | |
347 | |
348 if (tab_title.empty()) { | |
349 // If the page's title is empty use its security originator. | |
350 tab_title = GetSecurityOrigin(render_process_id, render_view_id); | |
351 } else { | |
352 // If the page's title matches its URL, use its security originator. | |
353 std::string languages = | |
354 content::GetContentClient()->browser()->GetAcceptLangs( | |
355 tab_content->GetBrowserContext()); | |
356 if (tab_title == net::FormatUrl(tab_content->GetURL(), languages)) | |
357 tab_title = GetSecurityOrigin(render_process_id, render_view_id); | |
358 } | |
359 | |
360 return tab_title; | |
361 } | |
362 | |
363 string16 MediaStreamCaptureIndicator::GetSecurityOrigin( | |
364 int render_process_id, int render_view_id) const { | |
365 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | |
366 WebContents* tab_content = tab_util::GetWebContentsByID( | |
367 render_process_id, render_view_id); | |
368 if (!tab_content) | |
369 return string16(); | |
370 | |
371 std::string security_origin = tab_content->GetURL().GetOrigin().spec(); | |
372 | |
373 // Remove the last character if it is a '/'. | |
374 if (!security_origin.empty()) { | |
375 std::string::iterator it = security_origin.end() - 1; | |
376 if (*it == '/') | |
377 security_origin.erase(it); | |
378 } | |
379 | |
380 return UTF8ToUTF16(security_origin); | |
381 } | |
OLD | NEW |