Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(4463)

Unified Diff: chrome/browser/media/media_stream_capture_indicator.cc

Issue 12035046: Fix bug causing tab favicon media indicator to not turn off. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Fix issue with browser shutdown race condition. Created 7 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
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();
}

Powered by Google App Engine
This is Rietveld 408576698