Chromium Code Reviews| Index: chrome/browser/extensions/api/tab_capture/tab_capture_registry.cc |
| diff --git a/chrome/browser/extensions/api/tab_capture/tab_capture_registry.cc b/chrome/browser/extensions/api/tab_capture/tab_capture_registry.cc |
| index 1526b7d066201a084d9cfb1442b5235fb79253c4..55519e750dfc4ce73d20c455dfdf4a2f82a45624 100644 |
| --- a/chrome/browser/extensions/api/tab_capture/tab_capture_registry.cc |
| +++ b/chrome/browser/extensions/api/tab_capture/tab_capture_registry.cc |
| @@ -5,14 +5,9 @@ |
| #include "chrome/browser/extensions/api/tab_capture/tab_capture_registry.h" |
| #include "base/lazy_instance.h" |
| -#include "chrome/browser/chrome_notification_types.h" |
| -#include "chrome/browser/ui/fullscreen/fullscreen_controller.h" |
| #include "components/keyed_service/content/browser_context_dependency_manager.h" |
| #include "content/public/browser/browser_thread.h" |
| -#include "content/public/browser/notification_details.h" |
| -#include "content/public/browser/notification_service.h" |
| -#include "content/public/browser/notification_source.h" |
| -#include "content/public/browser/render_view_host.h" |
| +#include "content/public/browser/render_frame_host.h" |
| #include "content/public/browser/web_contents.h" |
| #include "content/public/browser/web_contents_observer.h" |
| #include "extensions/browser/event_router.h" |
| @@ -28,6 +23,8 @@ namespace tab_capture = api::tab_capture; |
| class FullscreenObserver : public content::WebContentsObserver { |
| public: |
| + // Caller of this constructor must guarantee that |request->target_contents| |
| + // is a valid pointer (i.e., it will be dereferenced). |
|
ncarter (slow)
2014/07/10 01:17:51
Just say: "... is not NULL". The rest is implicit.
miu
2014/07/10 22:16:11
I think this was left over from earlier prototypin
|
| FullscreenObserver(TabCaptureRequest* request, |
| const TabCaptureRegistry* registry); |
| virtual ~FullscreenObserver() {} |
| @@ -36,6 +33,7 @@ class FullscreenObserver : public content::WebContentsObserver { |
| // content::WebContentsObserver implementation. |
| virtual void DidShowFullscreenWidget(int routing_id) OVERRIDE; |
| virtual void DidDestroyFullscreenWidget(int routing_id) OVERRIDE; |
| + virtual void DidToggleFullscreenModeForTab(bool entered_fullscreen) OVERRIDE; |
| TabCaptureRequest* request_; |
| const TabCaptureRegistry* registry_; |
| @@ -45,15 +43,13 @@ class FullscreenObserver : public content::WebContentsObserver { |
| // Holds all the state related to a tab capture stream. |
| struct TabCaptureRequest { |
| - TabCaptureRequest(int render_process_id, |
| - int render_view_id, |
| + TabCaptureRequest(content::WebContents* target_contents, |
| const std::string& extension_id, |
| int tab_id, |
| TabCaptureState status); |
| ~TabCaptureRequest(); |
| - const int render_process_id; |
| - const int render_view_id; |
| + content::WebContents* const target_contents; |
| const std::string extension_id; |
| const int tab_id; |
| TabCaptureState status; |
| @@ -65,12 +61,9 @@ struct TabCaptureRequest { |
| FullscreenObserver::FullscreenObserver( |
| TabCaptureRequest* request, |
| const TabCaptureRegistry* registry) |
| - : request_(request), |
| + : content::WebContentsObserver(request->target_contents), |
| + request_(request), |
| registry_(registry) { |
| - content::RenderViewHost* const rvh = |
| - content::RenderViewHost::FromID(request->render_process_id, |
| - request->render_view_id); |
| - Observe(rvh ? content::WebContents::FromRenderViewHost(rvh) : NULL); |
| } |
| void FullscreenObserver::DidShowFullscreenWidget( |
| @@ -85,18 +78,24 @@ void FullscreenObserver::DidDestroyFullscreenWidget( |
| registry_->DispatchStatusChangeEvent(request_); |
| } |
| +void FullscreenObserver::DidToggleFullscreenModeForTab( |
| + bool entered_fullscreen) { |
| + request_->fullscreen = entered_fullscreen; |
| + registry_->DispatchStatusChangeEvent(request_); |
| +} |
| + |
| TabCaptureRequest::TabCaptureRequest( |
| - int render_process_id, |
| - int render_view_id, |
| + content::WebContents* target_contents, |
| const std::string& extension_id, |
| const int tab_id, |
| TabCaptureState status) |
| - : render_process_id(render_process_id), |
| - render_view_id(render_view_id), |
| + : target_contents(target_contents), |
| extension_id(extension_id), |
| tab_id(tab_id), |
| status(status), |
| last_status(status), |
| + // TODO(miu): This initial value for |fullscreen| is a faulty assumption. |
| + // http://crbug.com/350491 |
| fullscreen(false) { |
| } |
| @@ -106,9 +105,6 @@ TabCaptureRequest::~TabCaptureRequest() { |
| TabCaptureRegistry::TabCaptureRegistry(content::BrowserContext* context) |
| : browser_context_(context), extension_registry_observer_(this) { |
| MediaCaptureDevicesDispatcher::GetInstance()->AddObserver(this); |
| - registrar_.Add(this, |
| - chrome::NOTIFICATION_FULLSCREEN_CHANGED, |
| - content::NotificationService::AllSources()); |
| extension_registry_observer_.Add(ExtensionRegistry::Get(browser_context_)); |
| } |
| @@ -143,44 +139,6 @@ const TabCaptureRegistry::RegistryCaptureInfo |
| return list; |
| } |
| -void TabCaptureRegistry::Observe(int type, |
| - const content::NotificationSource& source, |
| - const content::NotificationDetails& details) { |
| - DCHECK_CURRENTLY_ON(BrowserThread::UI); |
| - DCHECK_EQ(chrome::NOTIFICATION_FULLSCREEN_CHANGED, type); |
| - FullscreenController* fullscreen_controller = |
| - content::Source<FullscreenController>(source).ptr(); |
| - const bool is_fullscreen = *content::Details<bool>(details).ptr(); |
| - for (ScopedVector<TabCaptureRequest>::iterator it = requests_.begin(); |
| - it != requests_.end(); |
| - ++it) { |
| - // If we are exiting fullscreen mode, we only need to check if any of |
| - // the requests had the fullscreen flag toggled previously. The |
| - // fullscreen controller no longer has the reference to the fullscreen |
| - // web_contents here. |
| - if (!is_fullscreen) { |
| - if ((*it)->fullscreen) { |
| - (*it)->fullscreen = false; |
| - DispatchStatusChangeEvent(*it); |
| - break; |
| - } |
| - continue; |
| - } |
| - |
| - // If we are entering fullscreen mode, find whether the web_contents we |
| - // are capturing entered fullscreen mode. |
| - content::RenderViewHost* const rvh = content::RenderViewHost::FromID( |
| - (*it)->render_process_id, (*it)->render_view_id); |
| - if (rvh && |
| - fullscreen_controller->IsFullscreenForTabOrPending( |
| - content::WebContents::FromRenderViewHost(rvh))) { |
| - (*it)->fullscreen = true; |
| - DispatchStatusChangeEvent(*it); |
| - break; |
| - } |
| - } |
| -} |
| - |
| void TabCaptureRegistry::OnExtensionUnloaded( |
| content::BrowserContext* browser_context, |
| const Extension* extension, |
| @@ -196,53 +154,64 @@ void TabCaptureRegistry::OnExtensionUnloaded( |
| } |
| } |
| -bool TabCaptureRegistry::AddRequest(int render_process_id, |
| - int render_view_id, |
| +bool TabCaptureRegistry::AddRequest(content::WebContents* target_contents, |
| const std::string& extension_id, |
| int tab_id, |
| TabCaptureState status) { |
| - TabCaptureRequest* request = FindCaptureRequest(render_process_id, |
| - render_view_id); |
| + TabCaptureRequest* const request = FindCaptureRequest(target_contents); |
| + |
| // Currently, we do not allow multiple active captures for same tab. |
| if (request != NULL) { |
| if (request->status != tab_capture::TAB_CAPTURE_STATE_STOPPED && |
| request->status != tab_capture::TAB_CAPTURE_STATE_ERROR) { |
| return false; |
| } else { |
| - DeleteCaptureRequest(render_process_id, render_view_id); |
| + // Delete the request. |
| + // TODO(miu): It's not clear that this code path will ever get executed |
| + // and, in fact, it seems impossible that TabCaptureRequests will ever get |
| + // deleted. Probably the root cause of http://crbug.com/338445. |
|
ncarter (slow)
2014/07/10 01:17:51
If the entries of |requests_| are not properly cle
miu
2014/07/10 22:16:11
Done.
I used exactly your suggested approach of m
ncarter (slow)
2014/07/11 22:32:24
Wonderful, glad it worked out.
|
| + for (ScopedVector<TabCaptureRequest>::iterator it = requests_.begin(); |
| + it != requests_.end(); ++it) { |
| + if ((*it)->target_contents == target_contents) { |
| + requests_.erase(it); |
| + break; |
| + } |
| + } |
| } |
| } |
| - requests_.push_back(new TabCaptureRequest(render_process_id, |
| - render_view_id, |
| + requests_.push_back(new TabCaptureRequest(target_contents, |
| extension_id, |
| tab_id, |
| status)); |
| return true; |
| } |
| -bool TabCaptureRegistry::VerifyRequest(int render_process_id, |
| - int render_view_id) { |
| +bool TabCaptureRegistry::VerifyRequest( |
| + const content::WebContents* target_contents, |
| + const std::string& extension_id) { |
| DCHECK_CURRENTLY_ON(BrowserThread::UI); |
| - DVLOG(1) << "Verifying tabCapture request for " |
| - << render_process_id << ":" << render_view_id; |
| - // TODO(justinlin): Verify extension too. |
| - return (FindCaptureRequest(render_process_id, render_view_id) != NULL); |
| + TabCaptureRequest* const request = FindCaptureRequest(target_contents); |
| + // TODO(miu): We should probably also verify the origin, like the desktop |
| + // capture API. http://crbug.com/163100 |
| + return request && request->extension_id == extension_id; |
| } |
| void TabCaptureRegistry::OnRequestUpdate( |
| int render_process_id, |
| - int render_view_id, |
| - const content::MediaStreamDevice& device, |
| + int render_frame_id, |
| + content::MediaStreamType stream_type, |
| const content::MediaRequestState new_state) { |
| DCHECK_CURRENTLY_ON(BrowserThread::UI); |
| - if (device.type != content::MEDIA_TAB_VIDEO_CAPTURE && |
| - device.type != content::MEDIA_TAB_AUDIO_CAPTURE) { |
| + if (stream_type != content::MEDIA_TAB_VIDEO_CAPTURE && |
| + stream_type != content::MEDIA_TAB_AUDIO_CAPTURE) { |
| return; |
| } |
| - TabCaptureRequest* request = FindCaptureRequest(render_process_id, |
| - render_view_id); |
| + TabCaptureRequest* const request = FindCaptureRequest( |
| + content::WebContents::FromRenderFrameHost( |
| + content::RenderFrameHost::FromID( |
| + render_process_id, render_frame_id))); |
| if (request == NULL) { |
| // TODO(justinlin): This can happen because the extension's renderer does |
| // not seem to always cleanup streams correctly. |
| @@ -328,27 +297,13 @@ void TabCaptureRegistry::DispatchStatusChangeEvent( |
| } |
| TabCaptureRequest* TabCaptureRegistry::FindCaptureRequest( |
| - int render_process_id, int render_view_id) const { |
| + const content::WebContents* target_contents) const { |
| for (ScopedVector<TabCaptureRequest>::const_iterator it = requests_.begin(); |
| it != requests_.end(); ++it) { |
| - if ((*it)->render_process_id == render_process_id && |
| - (*it)->render_view_id == render_view_id) { |
| + if ((*it)->target_contents == target_contents) |
| return *it; |
| - } |
| } |
| return NULL; |
| } |
| -void TabCaptureRegistry::DeleteCaptureRequest(int render_process_id, |
| - int render_view_id) { |
| - for (ScopedVector<TabCaptureRequest>::iterator it = requests_.begin(); |
| - it != requests_.end(); ++it) { |
| - if ((*it)->render_process_id == render_process_id && |
| - (*it)->render_view_id == render_view_id) { |
| - requests_.erase(it); |
| - return; |
| - } |
| - } |
| -} |
| - |
| } // namespace extensions |