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/memory/scoped_ptr.h" | 10 #include "base/memory/scoped_ptr.h" |
11 #include "base/prefs/pref_service.h" | 11 #include "base/prefs/pref_service.h" |
12 #include "base/strings/utf_string_conversions.h" | 12 #include "base/strings/utf_string_conversions.h" |
13 #include "chrome/app/chrome_command_ids.h" | 13 #include "chrome/app/chrome_command_ids.h" |
14 #include "chrome/browser/browser_process.h" | 14 #include "chrome/browser/browser_process.h" |
15 #include "chrome/browser/extensions/extension_service.h" | 15 #include "chrome/browser/extensions/extension_service.h" |
16 #include "chrome/browser/profiles/profile.h" | 16 #include "chrome/browser/profiles/profile.h" |
17 #include "chrome/browser/status_icons/status_icon.h" | 17 #include "chrome/browser/status_icons/status_icon.h" |
18 #include "chrome/browser/status_icons/status_tray.h" | 18 #include "chrome/browser/status_icons/status_tray.h" |
19 #include "chrome/browser/tab_contents/tab_util.h" | 19 #include "chrome/browser/tab_contents/tab_util.h" |
| 20 #include "chrome/common/extensions/extension_constants.h" |
20 #include "chrome/common/pref_names.h" | 21 #include "chrome/common/pref_names.h" |
21 #include "content/public/browser/browser_thread.h" | 22 #include "content/public/browser/browser_thread.h" |
22 #include "content/public/browser/content_browser_client.h" | 23 #include "content/public/browser/content_browser_client.h" |
23 #include "content/public/browser/invalidate_type.h" | 24 #include "content/public/browser/invalidate_type.h" |
24 #include "content/public/browser/web_contents.h" | 25 #include "content/public/browser/web_contents.h" |
25 #include "content/public/browser/web_contents_delegate.h" | 26 #include "content/public/browser/web_contents_delegate.h" |
26 #include "content/public/browser/web_contents_observer.h" | 27 #include "content/public/browser/web_contents_observer.h" |
27 #include "extensions/common/extension.h" | 28 #include "extensions/common/extension.h" |
28 #include "grit/chromium_strings.h" | 29 #include "grit/chromium_strings.h" |
29 #include "grit/generated_resources.h" | 30 #include "grit/generated_resources.h" |
(...skipping 20 matching lines...) Expand all Loading... |
50 return NULL; | 51 return NULL; |
51 | 52 |
52 ExtensionService* extension_service = profile->GetExtensionService(); | 53 ExtensionService* extension_service = profile->GetExtensionService(); |
53 if (!extension_service) | 54 if (!extension_service) |
54 return NULL; | 55 return NULL; |
55 | 56 |
56 return extension_service->extensions()->GetExtensionOrAppByURL( | 57 return extension_service->extensions()->GetExtensionOrAppByURL( |
57 web_contents->GetURL()); | 58 web_contents->GetURL()); |
58 } | 59 } |
59 | 60 |
| 61 #if !defined(OS_ANDROID) |
| 62 |
| 63 bool IsWhitelistedExtension(const extensions::Extension* extension) { |
| 64 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
| 65 |
| 66 static const char* const kExtensionWhitelist[] = { |
| 67 extension_misc::kHotwordExtensionId, |
| 68 }; |
| 69 |
| 70 for (size_t i = 0; i < arraysize(kExtensionWhitelist); ++i) { |
| 71 if (extension->id() == kExtensionWhitelist[i]) |
| 72 return true; |
| 73 } |
| 74 |
| 75 return false; |
| 76 } |
| 77 |
| 78 #endif // !defined(OS_ANDROID) |
| 79 |
60 // Gets the security originator of the tab. It returns a string with no '/' | 80 // Gets the security originator of the tab. It returns a string with no '/' |
61 // at the end to display in the UI. | 81 // at the end to display in the UI. |
62 base::string16 GetSecurityOrigin(WebContents* web_contents) { | 82 base::string16 GetSecurityOrigin(WebContents* web_contents) { |
63 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 83 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
64 | 84 |
65 if (!web_contents) | 85 if (!web_contents) |
66 return base::string16(); | 86 return base::string16(); |
67 | 87 |
68 std::string security_origin = web_contents->GetURL().GetOrigin().spec(); | 88 std::string security_origin = web_contents->GetURL().GetOrigin().spec(); |
69 | 89 |
(...skipping 328 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
398 | 418 |
399 bool audio = false; | 419 bool audio = false; |
400 bool video = false; | 420 bool video = false; |
401 int command_id = IDC_MEDIA_CONTEXT_MEDIA_STREAM_CAPTURE_LIST_FIRST; | 421 int command_id = IDC_MEDIA_CONTEXT_MEDIA_STREAM_CAPTURE_LIST_FIRST; |
402 command_targets_.clear(); | 422 command_targets_.clear(); |
403 | 423 |
404 for (UsageMap::const_iterator iter = usage_map_.begin(); | 424 for (UsageMap::const_iterator iter = usage_map_.begin(); |
405 iter != usage_map_.end(); ++iter) { | 425 iter != usage_map_.end(); ++iter) { |
406 // Check if any audio and video devices have been used. | 426 // Check if any audio and video devices have been used. |
407 const WebContentsDeviceUsage& usage = *iter->second; | 427 const WebContentsDeviceUsage& usage = *iter->second; |
| 428 if (!usage.IsCapturingAudio() && !usage.IsCapturingVideo()) |
| 429 continue; |
| 430 |
408 WebContents* const web_contents = iter->first; | 431 WebContents* const web_contents = iter->first; |
409 | 432 |
410 // Audio/video icon is shown only for extensions or on Android. | 433 // The audio/video icon is shown only for non-whitelisted extensions or on |
411 // For regular tabs on desktop, we show an indicator in the tab icon. | 434 // Android. For regular tabs on desktop, we show an indicator in the tab |
412 if ((usage.IsCapturingAudio() || usage.IsCapturingVideo()) | 435 // icon. |
413 #if !defined(OS_ANDROID) | 436 #if !defined(OS_ANDROID) |
414 && GetExtension(web_contents) | 437 const extensions::Extension* extension = GetExtension(web_contents); |
| 438 if (!extension || IsWhitelistedExtension(extension)) |
| 439 continue; |
415 #endif | 440 #endif |
416 ) { | |
417 audio = audio || usage.IsCapturingAudio(); | |
418 video = video || usage.IsCapturingVideo(); | |
419 | 441 |
420 command_targets_.push_back(web_contents); | 442 audio = audio || usage.IsCapturingAudio(); |
421 menu->AddItem(command_id, GetTitle(web_contents)); | 443 video = video || usage.IsCapturingVideo(); |
422 | 444 |
423 // If the menu item is not a label, enable it. | 445 command_targets_.push_back(web_contents); |
424 menu->SetCommandIdEnabled(command_id, | 446 menu->AddItem(command_id, GetTitle(web_contents)); |
425 command_id != IDC_MinimumLabelValue); | |
426 | 447 |
427 // If reaching the maximum number, no more item will be added to the menu. | 448 // If the menu item is not a label, enable it. |
428 if (command_id == IDC_MEDIA_CONTEXT_MEDIA_STREAM_CAPTURE_LIST_LAST) | 449 menu->SetCommandIdEnabled(command_id, |
429 break; | 450 command_id != IDC_MinimumLabelValue); |
430 ++command_id; | 451 |
431 } | 452 // If reaching the maximum number, no more item will be added to the menu. |
| 453 if (command_id == IDC_MEDIA_CONTEXT_MEDIA_STREAM_CAPTURE_LIST_LAST) |
| 454 break; |
| 455 ++command_id; |
432 } | 456 } |
433 | 457 |
434 if (command_targets_.empty()) { | 458 if (command_targets_.empty()) { |
435 MaybeDestroyStatusTrayIcon(); | 459 MaybeDestroyStatusTrayIcon(); |
436 return; | 460 return; |
437 } | 461 } |
438 | 462 |
439 // The icon will take the ownership of the passed context menu. | 463 // The icon will take the ownership of the passed context menu. |
440 MaybeCreateStatusTrayIcon(audio, video); | 464 MaybeCreateStatusTrayIcon(audio, video); |
441 if (status_icon_) { | 465 if (status_icon_) { |
(...skipping 16 matching lines...) Expand all Loading... |
458 } else if (audio && !video) { | 482 } else if (audio && !video) { |
459 message_id = IDS_MEDIA_STREAM_STATUS_TRAY_TEXT_AUDIO_ONLY; | 483 message_id = IDS_MEDIA_STREAM_STATUS_TRAY_TEXT_AUDIO_ONLY; |
460 *image = *mic_image_; | 484 *image = *mic_image_; |
461 } else if (!audio && video) { | 485 } else if (!audio && video) { |
462 message_id = IDS_MEDIA_STREAM_STATUS_TRAY_TEXT_VIDEO_ONLY; | 486 message_id = IDS_MEDIA_STREAM_STATUS_TRAY_TEXT_VIDEO_ONLY; |
463 *image = *camera_image_; | 487 *image = *camera_image_; |
464 } | 488 } |
465 | 489 |
466 *tool_tip = l10n_util::GetStringUTF16(message_id); | 490 *tool_tip = l10n_util::GetStringUTF16(message_id); |
467 } | 491 } |
OLD | NEW |