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/logging.h" | 9 #include "base/logging.h" |
10 #include "base/utf_string_conversions.h" | 10 #include "base/utf_string_conversions.h" |
11 #include "chrome/app/chrome_command_ids.h" | 11 #include "chrome/app/chrome_command_ids.h" |
12 #include "chrome/browser/browser_process.h" | 12 #include "chrome/browser/browser_process.h" |
13 #include "chrome/browser/extensions/extension_service.h" | 13 #include "chrome/browser/extensions/extension_service.h" |
| 14 #include "chrome/browser/extensions/image_utils.h" |
14 #include "chrome/browser/profiles/profile.h" | 15 #include "chrome/browser/profiles/profile.h" |
15 #include "chrome/browser/status_icons/status_icon.h" | 16 #include "chrome/browser/status_icons/status_icon.h" |
16 #include "chrome/browser/status_icons/status_tray.h" | 17 #include "chrome/browser/status_icons/status_tray.h" |
17 #include "chrome/browser/tab_contents/tab_util.h" | 18 #include "chrome/browser/tab_contents/tab_util.h" |
18 #include "content/public/browser/browser_thread.h" | 19 #include "content/public/browser/browser_thread.h" |
19 #include "content/public/browser/content_browser_client.h" | 20 #include "content/public/browser/content_browser_client.h" |
20 #include "content/public/browser/render_view_host.h" | 21 #include "content/public/browser/render_view_host.h" |
21 #include "content/public/browser/web_contents.h" | 22 #include "content/public/browser/web_contents.h" |
22 #include "content/public/browser/web_contents_delegate.h" | 23 #include "content/public/browser/web_contents_delegate.h" |
23 #include "content/public/common/media_stream_request.h" | 24 #include "content/public/common/media_stream_request.h" |
(...skipping 93 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
117 const MediaStreamCaptureIndicator::CaptureDeviceTab& tab) { | 118 const MediaStreamCaptureIndicator::CaptureDeviceTab& tab) { |
118 return (render_process_id_ == tab.render_process_id && | 119 return (render_process_id_ == tab.render_process_id && |
119 render_view_id_ == tab.render_view_id); | 120 render_view_id_ == tab.render_view_id); |
120 } | 121 } |
121 | 122 |
122 MediaStreamCaptureIndicator::MediaStreamCaptureIndicator() | 123 MediaStreamCaptureIndicator::MediaStreamCaptureIndicator() |
123 : status_icon_(NULL), | 124 : status_icon_(NULL), |
124 mic_image_(NULL), | 125 mic_image_(NULL), |
125 camera_image_(NULL), | 126 camera_image_(NULL), |
126 balloon_image_(NULL), | 127 balloon_image_(NULL), |
127 request_index_(0) { | 128 icon_tracker_(this) { |
128 } | 129 } |
129 | 130 |
130 MediaStreamCaptureIndicator::~MediaStreamCaptureIndicator() { | 131 MediaStreamCaptureIndicator::~MediaStreamCaptureIndicator() { |
131 // The user is responsible for cleaning up by closing all the opened devices. | 132 // The user is responsible for cleaning up by closing all the opened devices. |
132 DCHECK(tabs_.empty()); | 133 DCHECK(tabs_.empty()); |
133 } | 134 } |
134 | 135 |
135 bool MediaStreamCaptureIndicator::IsCommandIdChecked( | 136 bool MediaStreamCaptureIndicator::IsCommandIdChecked( |
136 int command_id) const { | 137 int command_id) const { |
137 NOTIMPLEMENTED() << "There are no checked items in the MediaStream menu."; | 138 NOTIMPLEMENTED() << "There are no checked items in the MediaStream menu."; |
(...skipping 89 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
227 if (!g_browser_process) | 228 if (!g_browser_process) |
228 return; | 229 return; |
229 | 230 |
230 StatusTray* status_tray = g_browser_process->status_tray(); | 231 StatusTray* status_tray = g_browser_process->status_tray(); |
231 if (!status_tray) | 232 if (!status_tray) |
232 return; | 233 return; |
233 | 234 |
234 status_icon_ = status_tray->CreateStatusIcon(); | 235 status_icon_ = status_tray->CreateStatusIcon(); |
235 | 236 |
236 EnsureStatusTrayIconResources(); | 237 EnsureStatusTrayIconResources(); |
237 EnsureImageLoadingTracker(); | |
238 } | 238 } |
239 | 239 |
240 void MediaStreamCaptureIndicator::EnsureStatusTrayIconResources() { | 240 void MediaStreamCaptureIndicator::EnsureStatusTrayIconResources() { |
241 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 241 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
242 if (!mic_image_) { | 242 if (!mic_image_) { |
243 mic_image_ = ResourceBundle::GetSharedInstance().GetImageSkiaNamed( | 243 mic_image_ = ResourceBundle::GetSharedInstance().GetImageSkiaNamed( |
244 IDR_INFOBAR_MEDIA_STREAM_MIC); | 244 IDR_INFOBAR_MEDIA_STREAM_MIC); |
245 } | 245 } |
246 if (!camera_image_) { | 246 if (!camera_image_) { |
247 camera_image_ = ResourceBundle::GetSharedInstance().GetImageSkiaNamed( | 247 camera_image_ = ResourceBundle::GetSharedInstance().GetImageSkiaNamed( |
(...skipping 18 matching lines...) Expand all Loading... |
266 | 266 |
267 int message_id = IDS_MEDIA_STREAM_STATUS_TRAY_BALLOON_BODY_AUDIO_AND_VIDEO; | 267 int message_id = IDS_MEDIA_STREAM_STATUS_TRAY_BALLOON_BODY_AUDIO_AND_VIDEO; |
268 if (audio && !video) | 268 if (audio && !video) |
269 message_id = IDS_MEDIA_STREAM_STATUS_TRAY_BALLOON_BODY_AUDIO_ONLY; | 269 message_id = IDS_MEDIA_STREAM_STATUS_TRAY_BALLOON_BODY_AUDIO_ONLY; |
270 else if (!audio && video) | 270 else if (!audio && video) |
271 message_id = IDS_MEDIA_STREAM_STATUS_TRAY_BALLOON_BODY_VIDEO_ONLY; | 271 message_id = IDS_MEDIA_STREAM_STATUS_TRAY_BALLOON_BODY_VIDEO_ONLY; |
272 | 272 |
273 const extensions::Extension* extension = | 273 const extensions::Extension* extension = |
274 GetExtension(render_process_id, render_view_id); | 274 GetExtension(render_process_id, render_view_id); |
275 if (extension) { | 275 if (extension) { |
276 pending_messages_[request_index_++] = | 276 string16 message = |
277 l10n_util::GetStringFUTF16(message_id, | 277 l10n_util::GetStringFUTF16(message_id, |
278 UTF8ToUTF16(extension->name())); | 278 UTF8ToUTF16(extension->name())); |
279 tracker_->LoadImage( | 279 // TODO(mek): This used to use ImageLoadingTrackers caching. |
| 280 extension_image_utils::LoadImageAsync( |
280 extension, | 281 extension, |
281 extension->GetIconResource(32, ExtensionIconSet::MATCH_BIGGER), | 282 extension->GetIconResource(32, ExtensionIconSet::MATCH_BIGGER), |
282 gfx::Size(32, 32), | 283 gfx::Size(32, 32), |
283 ImageLoadingTracker::CACHE); | 284 base::Bind(&MediaStreamCaptureIndicator::OnImageLoaded, |
| 285 icon_tracker_.GetWeakPtr(), message)); |
284 return; | 286 return; |
285 } | 287 } |
286 | 288 |
287 string16 title = l10n_util::GetStringUTF16(IDS_PRODUCT_NAME); | 289 string16 title = l10n_util::GetStringUTF16(IDS_PRODUCT_NAME); |
288 string16 body = l10n_util::GetStringFUTF16(message_id, | 290 string16 body = l10n_util::GetStringFUTF16(message_id, |
289 GetSecurityOrigin(render_process_id, render_view_id)); | 291 GetSecurityOrigin(render_process_id, render_view_id)); |
290 status_icon_->DisplayBalloon(*balloon_image_, title, body); | 292 status_icon_->DisplayBalloon(*balloon_image_, title, body); |
291 } | 293 } |
292 | 294 |
293 void MediaStreamCaptureIndicator::OnImageLoaded( | 295 void MediaStreamCaptureIndicator::OnImageLoaded( |
294 const gfx::Image& image, | 296 const string16& message, |
295 const std::string& extension_id, | 297 const gfx::Image& image) { |
296 int index) { | |
297 string16 message; | |
298 message.swap(pending_messages_[index]); | |
299 pending_messages_.erase(index); | |
300 | |
301 const gfx::ImageSkia* image_skia = !image.IsEmpty() ? image.ToImageSkia() : | 298 const gfx::ImageSkia* image_skia = !image.IsEmpty() ? image.ToImageSkia() : |
302 ui::ResourceBundle::GetSharedInstance().GetImageSkiaNamed( | 299 ui::ResourceBundle::GetSharedInstance().GetImageSkiaNamed( |
303 IDR_APP_DEFAULT_ICON); | 300 IDR_APP_DEFAULT_ICON); |
304 status_icon_->DisplayBalloon(*image_skia, string16(), message); | 301 status_icon_->DisplayBalloon(*image_skia, string16(), message); |
305 } | 302 } |
306 | 303 |
307 void MediaStreamCaptureIndicator::Hide() { | 304 void MediaStreamCaptureIndicator::Hide() { |
308 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 305 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
309 DCHECK(tabs_.empty()); | 306 DCHECK(tabs_.empty()); |
310 | 307 |
311 // We have to destroy |tracker_| on the UI thread. | 308 // Make sure no more image loaded messages get delivered. |
312 tracker_.reset(); | 309 icon_tracker_.InvalidateWeakPtrs(); |
313 | 310 |
314 if (!status_icon_) | 311 if (!status_icon_) |
315 return; | 312 return; |
316 | 313 |
317 // If there is no browser process, we should not do anything. | 314 // If there is no browser process, we should not do anything. |
318 if (!g_browser_process) | 315 if (!g_browser_process) |
319 return; | 316 return; |
320 | 317 |
321 StatusTray* status_tray = g_browser_process->status_tray(); | 318 StatusTray* status_tray = g_browser_process->status_tray(); |
322 if (status_tray != NULL) { | 319 if (status_tray != NULL) { |
(...skipping 120 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
443 DCHECK_GE(iter->video_ref_count, 0); | 440 DCHECK_GE(iter->video_ref_count, 0); |
444 } | 441 } |
445 | 442 |
446 // Remove the tab if all the devices have been closed. | 443 // Remove the tab if all the devices have been closed. |
447 if (iter->audio_ref_count == 0 && iter->video_ref_count == 0) | 444 if (iter->audio_ref_count == 0 && iter->video_ref_count == 0) |
448 tabs_.erase(iter); | 445 tabs_.erase(iter); |
449 } | 446 } |
450 | 447 |
451 UpdateStatusTrayIconContextMenu(); | 448 UpdateStatusTrayIconContextMenu(); |
452 } | 449 } |
453 | |
454 void MediaStreamCaptureIndicator::EnsureImageLoadingTracker() { | |
455 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | |
456 if (tracker_.get()) | |
457 return; | |
458 | |
459 tracker_.reset(new ImageLoadingTracker(this)); | |
460 pending_messages_.clear(); | |
461 request_index_ = 0; | |
462 } | |
OLD | NEW |