Index: chrome/browser/media/media_stream_capture_indicator.cc |
diff --git a/chrome/browser/media/media_stream_capture_indicator.cc b/chrome/browser/media/media_stream_capture_indicator.cc |
index 6cc6b5323e0502019e87b08d80edc5f69aaba0a4..a7b4b6557fcf7067bba6c95d735a6dd34c8a5cff 100644 |
--- a/chrome/browser/media/media_stream_capture_indicator.cc |
+++ b/chrome/browser/media/media_stream_capture_indicator.cc |
@@ -7,6 +7,7 @@ |
#include "base/bind.h" |
#include "base/i18n/rtl.h" |
#include "base/logging.h" |
+#include "base/memory/scoped_ptr.h" |
#include "base/utf_string_conversions.h" |
#include "chrome/app/chrome_command_ids.h" |
#include "chrome/browser/browser_process.h" |
@@ -19,28 +20,25 @@ |
#include "content/public/browser/browser_thread.h" |
#include "content/public/browser/content_browser_client.h" |
#include "content/public/browser/invalidate_type.h" |
-#include "content/public/browser/render_view_host.h" |
#include "content/public/browser/web_contents.h" |
#include "content/public/browser/web_contents_delegate.h" |
-#include "content/public/common/media_stream_request.h" |
+#include "content/public/browser/web_contents_observer.h" |
#include "grit/chromium_strings.h" |
#include "grit/generated_resources.h" |
#include "grit/theme_resources.h" |
#include "net/base/net_util.h" |
#include "ui/base/l10n/l10n_util.h" |
#include "ui/base/resource/resource_bundle.h" |
+#include "ui/gfx/image/image_skia.h" |
using content::BrowserThread; |
using content::WebContents; |
namespace { |
-const extensions::Extension* GetExtension(int render_process_id, |
- int render_view_id) { |
+const extensions::Extension* GetExtension(WebContents* web_contents) { |
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
- WebContents* web_contents = tab_util::GetWebContentsByID( |
- render_process_id, render_view_id); |
if (!web_contents) |
return NULL; |
@@ -59,14 +57,13 @@ const extensions::Extension* GetExtension(int render_process_id, |
// Gets the security originator of the tab. It returns a string with no '/' |
// at the end to display in the UI. |
-string16 GetSecurityOrigin(int render_process_id, int render_view_id) { |
+string16 GetSecurityOrigin(WebContents* web_contents) { |
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
- WebContents* tab_content = tab_util::GetWebContentsByID( |
- render_process_id, render_view_id); |
- if (!tab_content) |
+ |
+ if (!web_contents) |
return string16(); |
- std::string security_origin = tab_content->GetURL().GetOrigin().spec(); |
+ std::string security_origin = web_contents->GetURL().GetOrigin().spec(); |
// Remove the last character if it is a '/'. |
if (!security_origin.empty()) { |
@@ -78,31 +75,28 @@ string16 GetSecurityOrigin(int render_process_id, int render_view_id) { |
return UTF8ToUTF16(security_origin); |
} |
-string16 GetTitle(int render_process_id, int render_view_id) { |
+string16 GetTitle(WebContents* web_contents) { |
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
- const extensions::Extension* extension = |
- GetExtension(render_process_id, render_view_id); |
+ if (!web_contents) |
+ return string16(); |
+ |
+ const extensions::Extension* const extension = GetExtension(web_contents); |
if (extension) |
return UTF8ToUTF16(extension->name()); |
- WebContents* tab_content = tab_util::GetWebContentsByID( |
- render_process_id, render_view_id); |
- if (!tab_content) |
- return string16(); |
- |
- string16 tab_title = tab_content->GetTitle(); |
+ string16 tab_title = web_contents->GetTitle(); |
if (tab_title.empty()) { |
// If the page's title is empty use its security originator. |
- tab_title = GetSecurityOrigin(render_process_id, render_view_id); |
+ tab_title = GetSecurityOrigin(web_contents); |
} else { |
// If the page's title matches its URL, use its security originator. |
std::string languages = |
content::GetContentClient()->browser()->GetAcceptLangs( |
- tab_content->GetBrowserContext()); |
- if (tab_title == net::FormatUrl(tab_content->GetURL(), languages)) |
- tab_title = GetSecurityOrigin(render_process_id, render_view_id); |
+ web_contents->GetBrowserContext()); |
+ if (tab_title == net::FormatUrl(web_contents->GetURL(), languages)) |
+ tab_title = GetSecurityOrigin(web_contents); |
} |
return tab_title; |
@@ -110,18 +104,73 @@ string16 GetTitle(int render_process_id, int render_view_id) { |
} // namespace |
-MediaStreamCaptureIndicator::TabEquals::TabEquals(WebContents* web_contents, |
- int render_process_id, |
- int render_view_id) |
- : web_contents_(web_contents), |
- render_process_id_(render_process_id), |
- render_view_id_(render_view_id) {} |
- |
-bool MediaStreamCaptureIndicator::TabEquals::operator() ( |
- const MediaStreamCaptureIndicator::CaptureDeviceTab& tab) { |
- return (web_contents_ == tab.web_contents || |
- (render_process_id_ == tab.render_process_id && |
- render_view_id_ == tab.render_view_id)); |
+// Stores usage counts for all the capture devices associated with a single |
+// WebContents instance, and observes for the destruction of the WebContents |
+// instance. |
+class MediaStreamCaptureIndicator::WebContentsDeviceUsage |
+ : protected content::WebContentsObserver { |
+ public: |
+ explicit WebContentsDeviceUsage(WebContents* web_contents); |
+ |
+ bool IsWebContentsDestroyed() const { return web_contents() == NULL; } |
+ |
+ bool IsCapturingAudio() const { return audio_ref_count_ > 0; } |
+ bool IsCapturingVideo() const { return video_ref_count_ > 0; } |
+ bool IsMirroring() const { return mirroring_ref_count_ > 0; } |
+ |
+ // Updates ref-counts up (|direction| is true) or down by one, based on the |
+ // type of each device provided. In the increment-upward case, the return |
+ // value is the message ID for the balloon body to show, or zero if the |
+ // balloon should not be shown. |
+ int TallyUsage(const content::MediaStreamDevices& devices, bool direction); |
+ |
+ private: |
+ int audio_ref_count_; |
+ int video_ref_count_; |
+ int mirroring_ref_count_; |
+ |
+ DISALLOW_COPY_AND_ASSIGN(WebContentsDeviceUsage); |
+}; |
+ |
+MediaStreamCaptureIndicator::WebContentsDeviceUsage::WebContentsDeviceUsage( |
+ WebContents* web_contents) |
+ : content::WebContentsObserver(web_contents), |
+ audio_ref_count_(0), video_ref_count_(0), mirroring_ref_count_(0) { |
+} |
+ |
+int MediaStreamCaptureIndicator::WebContentsDeviceUsage::TallyUsage( |
+ const content::MediaStreamDevices& devices, bool direction) { |
+ const int inc_amount = direction ? +1 : -1; |
+ bool incremented_audio_count = false; |
+ bool incremented_video_count = false; |
+ for (content::MediaStreamDevices::const_iterator it = devices.begin(); |
+ it != devices.end(); ++it) { |
+ if (it->type == content::MEDIA_TAB_AUDIO_CAPTURE || |
+ it->type == content::MEDIA_TAB_VIDEO_CAPTURE) { |
+ mirroring_ref_count_ += inc_amount; |
+ } else if (content::IsAudioMediaType(it->type)) { |
+ audio_ref_count_ += inc_amount; |
+ incremented_audio_count = (inc_amount > 0); |
+ } else if (content::IsVideoMediaType(it->type)) { |
+ video_ref_count_ += inc_amount; |
+ incremented_video_count = (inc_amount > 0); |
+ } else { |
+ NOTIMPLEMENTED(); |
+ } |
+ } |
+ |
+ DCHECK_LE(0, audio_ref_count_); |
+ DCHECK_LE(0, video_ref_count_); |
+ DCHECK_LE(0, mirroring_ref_count_); |
+ |
+ if (incremented_audio_count && incremented_video_count) |
+ return IDS_MEDIA_STREAM_STATUS_TRAY_BALLOON_BODY_AUDIO_AND_VIDEO; |
+ else if (incremented_audio_count) |
+ return IDS_MEDIA_STREAM_STATUS_TRAY_BALLOON_BODY_AUDIO_ONLY; |
+ else if (incremented_video_count) |
+ return IDS_MEDIA_STREAM_STATUS_TRAY_BALLOON_BODY_VIDEO_ONLY; |
+ else |
+ return 0; |
} |
MediaStreamCaptureIndicator::MediaStreamCaptureIndicator() |
@@ -133,8 +182,19 @@ MediaStreamCaptureIndicator::MediaStreamCaptureIndicator() |
} |
MediaStreamCaptureIndicator::~MediaStreamCaptureIndicator() { |
- // The user is responsible for cleaning up by closing all the opened devices. |
- DCHECK(tabs_.empty()); |
+ // The user is responsible for cleaning up by reporting the closure of any |
+ // opened devices. However, there exists a race condition at shutdown: The UI |
+ // thread may be stopped before CaptureDevicesClosed() posts the task to |
+ // invoke DoDevicesClosedOnUIThread(). In this case, usage_map_ won't be |
+ // empty like it should. |
+ DCHECK(usage_map_.empty() || |
+ !BrowserThread::IsMessageLoopValid(BrowserThread::UI)); |
+ |
+ // Free any WebContentsDeviceUsage objects left over. |
+ for (UsageMap::const_iterator it = usage_map_.begin(); it != usage_map_.end(); |
+ ++it) { |
+ delete it->second; |
+ } |
} |
bool MediaStreamCaptureIndicator::IsCommandIdChecked( |
@@ -156,18 +216,16 @@ bool MediaStreamCaptureIndicator::GetAcceleratorForCommandId( |
void MediaStreamCaptureIndicator::ExecuteCommand(int command_id) { |
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
- DCHECK(command_id >= IDC_MEDIA_CONTEXT_MEDIA_STREAM_CAPTURE_LIST_FIRST && |
- command_id <= IDC_MEDIA_CONTEXT_MEDIA_STREAM_CAPTURE_LIST_LAST); |
- int index = command_id - IDC_MEDIA_CONTEXT_MEDIA_STREAM_CAPTURE_LIST_FIRST; |
- WebContents* web_content = tab_util::GetWebContentsByID( |
- tabs_[index].render_process_id, tabs_[index].render_view_id); |
- DCHECK(web_content); |
- if (!web_content) { |
- NOTREACHED(); |
- return; |
- } |
- web_content->GetDelegate()->ActivateContents(web_content); |
+ const int index = |
+ command_id - IDC_MEDIA_CONTEXT_MEDIA_STREAM_CAPTURE_LIST_FIRST; |
+ DCHECK_LE(0, index); |
+ DCHECK_GT(static_cast<int>(command_targets_.size()), index); |
+ WebContents* const web_contents = command_targets_[index]; |
+ UsageMap::const_iterator it = usage_map_.find(web_contents); |
+ if (it == usage_map_.end() || it->second->IsWebContentsDestroyed()) |
+ return; |
+ web_contents->GetDelegate()->ActivateContents(web_contents); |
} |
void MediaStreamCaptureIndicator::CaptureDevicesOpened( |
@@ -202,9 +260,7 @@ void MediaStreamCaptureIndicator::DoDevicesOpenedOnUIThread( |
const content::MediaStreamDevices& devices) { |
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
- CreateStatusTray(); |
- |
- AddCaptureDeviceTab(render_process_id, render_view_id, devices); |
+ AddCaptureDevices(render_process_id, render_view_id, devices); |
} |
void MediaStreamCaptureIndicator::DoDevicesClosedOnUIThread( |
@@ -213,10 +269,10 @@ void MediaStreamCaptureIndicator::DoDevicesClosedOnUIThread( |
const content::MediaStreamDevices& devices) { |
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
- RemoveCaptureDeviceTab(render_process_id, render_view_id, devices); |
+ RemoveCaptureDevices(render_process_id, render_view_id, devices); |
} |
-void MediaStreamCaptureIndicator::CreateStatusTray() { |
+void MediaStreamCaptureIndicator::MaybeCreateStatusTrayIcon() { |
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
if (status_icon_) |
return; |
@@ -254,34 +310,20 @@ void MediaStreamCaptureIndicator::EnsureStatusTrayIconResources() { |
} |
void MediaStreamCaptureIndicator::ShowBalloon( |
- int render_process_id, |
- int render_view_id, |
- bool audio, |
- bool video) { |
+ WebContents* web_contents, int balloon_body_message_id) { |
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
- DCHECK(audio || video); |
- |
- int message_id = IDS_MEDIA_STREAM_STATUS_TRAY_BALLOON_BODY_AUDIO_AND_VIDEO; |
- if (audio && !video) |
- message_id = IDS_MEDIA_STREAM_STATUS_TRAY_BALLOON_BODY_AUDIO_ONLY; |
- else if (!audio && video) |
- message_id = IDS_MEDIA_STREAM_STATUS_TRAY_BALLOON_BODY_VIDEO_ONLY; |
+ DCHECK_NE(0, balloon_body_message_id); |
// Only show the balloon for extensions. |
- const extensions::Extension* extension = |
- GetExtension(render_process_id, render_view_id); |
+ const extensions::Extension* const extension = GetExtension(web_contents); |
if (!extension) { |
DVLOG(1) << "Balloon is shown only for extensions"; |
return; |
} |
string16 message = |
- l10n_util::GetStringFUTF16(message_id, |
+ l10n_util::GetStringFUTF16(balloon_body_message_id, |
UTF8ToUTF16(extension->name())); |
- |
- WebContents* web_contents = tab_util::GetWebContentsByID( |
- render_process_id, render_view_id); |
- |
Profile* profile = |
Profile::FromBrowserContext(web_contents->GetBrowserContext()); |
@@ -297,7 +339,7 @@ void MediaStreamCaptureIndicator::ShowBalloon( |
void MediaStreamCaptureIndicator::OnImageLoaded( |
const string16& message, |
const gfx::Image& image) { |
- if (!should_show_balloon_) |
+ if (!should_show_balloon_ || !status_icon_) |
return; |
const gfx::ImageSkia* image_skia = !image.IsEmpty() ? image.ToImageSkia() : |
@@ -306,7 +348,7 @@ void MediaStreamCaptureIndicator::OnImageLoaded( |
status_icon_->DisplayBalloon(*image_skia, string16(), message); |
} |
-void MediaStreamCaptureIndicator::Hide() { |
+void MediaStreamCaptureIndicator::MaybeDestroyStatusTrayIcon() { |
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
// Make sure images that finish loading don't cause a balloon to be shown. |
@@ -333,44 +375,46 @@ void MediaStreamCaptureIndicator::UpdateStatusTrayIconContextMenu() { |
bool audio = false; |
bool video = false; |
int command_id = IDC_MEDIA_CONTEXT_MEDIA_STREAM_CAPTURE_LIST_FIRST; |
- for (CaptureDeviceTabs::iterator iter = tabs_.begin(); |
- iter != tabs_.end();) { |
- string16 tab_title = GetTitle(iter->render_process_id, |
- iter->render_view_id); |
- if (tab_title.empty()) { |
- // Delete the entry since the tab has gone away. |
- iter = tabs_.erase(iter); |
+ command_targets_.clear(); |
+ for (UsageMap::const_iterator iter = usage_map_.begin(); |
+ iter != usage_map_.end(); ++iter) { |
+ // Check if any audio and video devices have been used. |
+ const WebContentsDeviceUsage& usage = *iter->second; |
+ if (usage.IsWebContentsDestroyed() || |
+ (!usage.IsCapturingAudio() && !usage.IsCapturingVideo())) { |
continue; |
} |
+ audio = audio || usage.IsCapturingAudio(); |
+ video = video || usage.IsCapturingVideo(); |
- // Check if any audio and video devices have been used. |
- audio = audio || iter->audio_ref_count > 0; |
- video = video || iter->video_ref_count > 0; |
- |
- menu->AddItem(command_id, tab_title); |
+ WebContents* const web_contents = iter->first; |
+ command_targets_.push_back(web_contents); |
+ menu->AddItem(command_id, GetTitle(web_contents)); |
// If reaching the maximum number, no more item will be added to the menu. |
if (command_id == IDC_MEDIA_CONTEXT_MEDIA_STREAM_CAPTURE_LIST_LAST) |
break; |
- |
++command_id; |
- ++iter; |
} |
- if (!audio && !video) { |
- Hide(); |
+ if (command_targets_.empty()) { |
+ MaybeDestroyStatusTrayIcon(); |
return; |
} |
// The icon will take the ownership of the passed context menu. |
- status_icon_->SetContextMenu(menu.release()); |
- UpdateStatusTrayIconDisplay(audio, video); |
+ MaybeCreateStatusTrayIcon(); |
+ if (status_icon_) { |
+ status_icon_->SetContextMenu(menu.release()); |
+ UpdateStatusTrayIconDisplay(audio, video); |
+ } |
} |
void MediaStreamCaptureIndicator::UpdateStatusTrayIconDisplay( |
bool audio, bool video) { |
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
DCHECK(audio || video); |
+ DCHECK(status_icon_); |
int message_id = 0; |
if (audio && video) { |
message_id = IDS_MEDIA_STREAM_STATUS_TRAY_TEXT_AUDIO_AND_VIDEO; |
@@ -387,135 +431,111 @@ void MediaStreamCaptureIndicator::UpdateStatusTrayIconDisplay( |
message_id, l10n_util::GetStringUTF16(IDS_PRODUCT_NAME))); |
} |
-void MediaStreamCaptureIndicator::AddCaptureDeviceTab( |
+WebContents* MediaStreamCaptureIndicator::LookUpByKnownAlias( |
+ int render_process_id, int render_view_id) const { |
+ DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
+ |
+ WebContents* result = |
+ tab_util::GetWebContentsByID(render_process_id, render_view_id); |
+ if (!result) { |
+ const RenderViewIDs key(render_process_id, render_view_id); |
+ AliasMap::const_iterator it = aliases_.find(key); |
+ if (it != aliases_.end()) |
+ result = it->second; |
+ } |
+ return result; |
+} |
+ |
+void MediaStreamCaptureIndicator::AddCaptureDevices( |
int render_process_id, |
int render_view_id, |
const content::MediaStreamDevices& devices) { |
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
- WebContents* web_contents = tab_util::GetWebContentsByID(render_process_id, |
- render_view_id); |
+ WebContents* const web_contents = |
+ LookUpByKnownAlias(render_process_id, render_view_id); |
if (!web_contents) |
return; |
- CaptureDeviceTabs::iterator iter = std::find_if( |
- tabs_.begin(), tabs_.end(), TabEquals(web_contents, |
- render_process_id, |
- render_view_id)); |
- if (iter == tabs_.end()) { |
- tabs_.push_back(CaptureDeviceTab(web_contents, |
- render_process_id, |
- render_view_id)); |
- iter = tabs_.end() - 1; |
- } |
+ // Increase the usage ref-counts. |
+ WebContentsDeviceUsage*& usage = usage_map_[web_contents]; |
+ if (!usage) |
+ usage = new WebContentsDeviceUsage(web_contents); |
+ const int balloon_body_message_id = usage->TallyUsage(devices, true); |
- bool audio = false; |
- bool video = false; |
- bool tab_capture = false; |
- content::MediaStreamDevices::const_iterator dev = devices.begin(); |
- for (; dev != devices.end(); ++dev) { |
- if (dev->type == content::MEDIA_TAB_AUDIO_CAPTURE || |
- dev->type == content::MEDIA_TAB_VIDEO_CAPTURE) { |
- ++iter->tab_capture_ref_count; |
- tab_capture = true; |
- } else if (content::IsAudioMediaType(dev->type)) { |
- ++iter->audio_ref_count; |
- audio = true; |
- } else if (content::IsVideoMediaType(dev->type)) { |
- ++iter->video_ref_count; |
- video = true; |
- } else { |
- NOTIMPLEMENTED(); |
- } |
- } |
+ // Keep track of the IDs as a known alias to the WebContents instance. |
+ const AliasMap::iterator insert_it = aliases_.insert( |
+ make_pair(RenderViewIDs(render_process_id, render_view_id), |
+ web_contents)).first; |
+ DCHECK_EQ(web_contents, insert_it->second) |
+ << "BUG: IDs refer to two different WebContents instances."; |
- DCHECK(web_contents); |
web_contents->NotifyNavigationStateChanged(content::INVALIDATE_TYPE_TAB); |
- // Don't use desktop notifications for tab capture. We use a favicon |
- // glow notification instead. |
- if (!status_icon_ || tab_capture) |
- return; |
- |
UpdateStatusTrayIconContextMenu(); |
- ShowBalloon(render_process_id, render_view_id, audio, video); |
+ if (balloon_body_message_id) |
+ ShowBalloon(web_contents, balloon_body_message_id); |
} |
-void MediaStreamCaptureIndicator::RemoveCaptureDeviceTab( |
+void MediaStreamCaptureIndicator::RemoveCaptureDevices( |
int render_process_id, |
int render_view_id, |
const content::MediaStreamDevices& devices) { |
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
- WebContents* web_contents = tab_util::GetWebContentsByID(render_process_id, |
- render_view_id); |
- CaptureDeviceTabs::iterator iter = std::find_if( |
- tabs_.begin(), tabs_.end(), TabEquals(web_contents, |
- render_process_id, |
- render_view_id)); |
- |
- if (iter != tabs_.end()) { |
- content::MediaStreamDevices::const_iterator dev = devices.begin(); |
- for (; dev != devices.end(); ++dev) { |
- if (dev->type == content::MEDIA_TAB_AUDIO_CAPTURE || |
- dev->type == content::MEDIA_TAB_VIDEO_CAPTURE) { |
- --iter->tab_capture_ref_count; |
- } else if (content::IsAudioMediaType(dev->type)) { |
- --iter->audio_ref_count; |
- } else if (content::IsVideoMediaType(dev->type)) { |
- --iter->video_ref_count; |
- } else { |
- NOTIMPLEMENTED(); |
- } |
- |
- DCHECK_GE(iter->audio_ref_count, 0); |
- DCHECK_GE(iter->video_ref_count, 0); |
- } |
- // Remove the tab if all the devices have been closed. |
- if (iter->audio_ref_count == 0 && iter->video_ref_count == 0 && |
- iter->tab_capture_ref_count == 0) |
- tabs_.erase(iter); |
- } |
+ WebContents* const web_contents = |
+ LookUpByKnownAlias(render_process_id, render_view_id); |
+ if (!web_contents) |
+ return; |
- if (web_contents) |
+ // Decrease the usage ref-counts. |
+ WebContentsDeviceUsage* const usage = usage_map_[web_contents]; |
+ DCHECK(usage); |
+ usage->TallyUsage(devices, false); |
+ |
+ if (!usage->IsWebContentsDestroyed()) |
web_contents->NotifyNavigationStateChanged(content::INVALIDATE_TYPE_TAB); |
- if (!status_icon_) |
- return; |
+ // Remove the usage and alias mappings if all the devices have been closed. |
+ if (!usage->IsCapturingAudio() && !usage->IsCapturingVideo() && |
+ !usage->IsMirroring()) { |
+ for (AliasMap::iterator alias_it = aliases_.begin(); |
+ alias_it != aliases_.end(); ) { |
+ if (alias_it->second == web_contents) |
+ aliases_.erase(alias_it++); |
+ else |
+ ++alias_it; |
+ } |
+ delete usage; |
+ usage_map_.erase(web_contents); |
+ } |
UpdateStatusTrayIconContextMenu(); |
} |
-bool MediaStreamCaptureIndicator::IsProcessCapturing(int render_process_id, |
- int render_view_id) const { |
+bool MediaStreamCaptureIndicator::IsCapturingUserMedia( |
+ int render_process_id, int render_view_id) const { |
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
- WebContents* web_contents = tab_util::GetWebContentsByID(render_process_id, |
- render_view_id); |
+ |
+ WebContents* const web_contents = |
+ LookUpByKnownAlias(render_process_id, render_view_id); |
if (!web_contents) |
return false; |
- CaptureDeviceTabs::const_iterator iter = std::find_if( |
- tabs_.begin(), tabs_.end(), TabEquals(web_contents, |
- render_process_id, |
- render_view_id)); |
- if (iter == tabs_.end()) |
- return false; |
- return (iter->audio_ref_count > 0 || iter->video_ref_count > 0); |
+ UsageMap::const_iterator it = usage_map_.find(web_contents); |
+ return (it != usage_map_.end() && |
+ (it->second->IsCapturingAudio() || it->second->IsCapturingVideo())); |
} |
-bool MediaStreamCaptureIndicator::IsProcessCapturingTab( |
+bool MediaStreamCaptureIndicator::IsBeingMirrored( |
int render_process_id, int render_view_id) const { |
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
- WebContents* web_contents = tab_util::GetWebContentsByID(render_process_id, |
- render_view_id); |
+ |
+ WebContents* const web_contents = |
+ LookUpByKnownAlias(render_process_id, render_view_id); |
if (!web_contents) |
return false; |
- CaptureDeviceTabs::const_iterator iter = std::find_if( |
- tabs_.begin(), tabs_.end(), TabEquals(web_contents, |
- render_process_id, |
- render_view_id)); |
- if (iter == tabs_.end()) |
- return false; |
- return (iter->tab_capture_ref_count > 0); |
+ UsageMap::const_iterator it = usage_map_.find(web_contents); |
+ return it != usage_map_.end() && it->second->IsMirroring(); |
} |