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

Side by Side Diff: chrome/browser/extensions/api/tab_capture/tab_capture_registry.cc

Issue 364123002: [Cross-Site Isolation] Migrate entire MediaStream verticals to be per-RenderFrame. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: It's random enough. + REBASE Created 6 years, 5 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 unified diff | Download patch | Annotate | Revision Log
OLDNEW
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/extensions/api/tab_capture/tab_capture_registry.h" 5 #include "chrome/browser/extensions/api/tab_capture/tab_capture_registry.h"
6 6
7 #include "base/lazy_instance.h" 7 #include "base/lazy_instance.h"
8 #include "chrome/browser/chrome_notification_types.h" 8 #include "base/values.h"
9 #include "chrome/browser/ui/fullscreen/fullscreen_controller.h" 9 #include "chrome/browser/sessions/session_id.h"
10 #include "components/keyed_service/content/browser_context_dependency_manager.h" 10 #include "components/keyed_service/content/browser_context_dependency_manager.h"
11 #include "content/public/browser/browser_thread.h" 11 #include "content/public/browser/browser_thread.h"
12 #include "content/public/browser/notification_details.h" 12 #include "content/public/browser/render_frame_host.h"
13 #include "content/public/browser/notification_service.h"
14 #include "content/public/browser/notification_source.h"
15 #include "content/public/browser/render_view_host.h"
16 #include "content/public/browser/web_contents.h" 13 #include "content/public/browser/web_contents.h"
17 #include "content/public/browser/web_contents_observer.h" 14 #include "content/public/browser/web_contents_observer.h"
18 #include "extensions/browser/event_router.h" 15 #include "extensions/browser/event_router.h"
19 #include "extensions/browser/extension_registry.h" 16 #include "extensions/browser/extension_registry.h"
20 #include "extensions/common/extension.h" 17 #include "extensions/common/extension.h"
21 18
22 using content::BrowserThread; 19 using content::BrowserThread;
23 using extensions::tab_capture::TabCaptureState; 20 using extensions::tab_capture::TabCaptureState;
24 21
25 namespace extensions { 22 namespace extensions {
26 23
27 namespace tab_capture = api::tab_capture; 24 namespace tab_capture = api::tab_capture;
28 25
29 class FullscreenObserver : public content::WebContentsObserver { 26 // Stores values associated with a tab capture request, maintains lifecycle
27 // state, and monitors WebContents for fullscreen transition events and
28 // destruction.
29 class TabCaptureRegistry::LiveRequest : public content::WebContentsObserver {
30 public: 30 public:
31 FullscreenObserver(TabCaptureRequest* request, 31 LiveRequest(content::WebContents* target_contents,
32 const TabCaptureRegistry* registry); 32 const std::string& extension_id,
33 virtual ~FullscreenObserver() {} 33 TabCaptureRegistry* registry)
34 : content::WebContentsObserver(target_contents),
35 extension_id_(extension_id),
36 registry_(registry),
37 capture_state_(tab_capture::TAB_CAPTURE_STATE_NONE),
38 is_verified_(false),
39 // TODO(miu): This initial value for |is_fullscreened_| is a faulty
40 // assumption. http://crbug.com/350491
41 is_fullscreened_(false),
42 render_process_id_(-1),
43 render_frame_id_(-1) {
44 DCHECK(web_contents());
45 DCHECK(registry_);
46 }
47
48 virtual ~LiveRequest() {}
49
50 // Accessors.
51 const content::WebContents* target_contents() const {
52 return content::WebContentsObserver::web_contents();
53 }
54 const std::string& extension_id() const {
55 return extension_id_;
56 }
57 TabCaptureState capture_state() const {
58 return capture_state_;
59 }
60 bool is_verified() const {
61 return is_verified_;
62 }
63
64 void SetIsVerified() {
65 DCHECK(!is_verified_);
66 is_verified_ = true;
67 }
68
69 // TODO(miu): See TODO(miu) in VerifyRequest() below.
70 void SetOriginallyTargettedRenderFrameID(int render_process_id,
71 int render_frame_id) {
72 DCHECK_GT(render_frame_id, 0);
73 DCHECK_EQ(render_frame_id_, -1); // Setting ID only once.
74 render_process_id_ = render_process_id;
75 render_frame_id_ = render_frame_id;
76 }
77
78 bool WasOriginallyTargettingRenderFrameID(int render_process_id,
79 int render_frame_id) const {
80 return render_process_id_ == render_process_id &&
81 render_frame_id_ == render_frame_id;
82 }
83
84 void UpdateCaptureState(TabCaptureState next_capture_state) {
85 // This method can get duplicate calls if both audio and video were
86 // requested, so return early to avoid duplicate dispatching of status
87 // change events.
88 if (capture_state_ == next_capture_state)
89 return;
90
91 capture_state_ = next_capture_state;
92 registry_->DispatchStatusChangeEvent(this);
93 }
94
95 void GetCaptureInfo(tab_capture::CaptureInfo* info) const {
96 info->tab_id = SessionID::IdForTab(web_contents());
97 info->status = capture_state_;
98 info->fullscreen = is_fullscreened_;
99 }
100
101 protected:
102 virtual void DidShowFullscreenWidget(int routing_id) OVERRIDE {
103 is_fullscreened_ = true;
104 if (capture_state_ == tab_capture::TAB_CAPTURE_STATE_ACTIVE)
105 registry_->DispatchStatusChangeEvent(this);
106 }
107
108 virtual void DidDestroyFullscreenWidget(int routing_id) OVERRIDE {
109 is_fullscreened_ = false;
110 if (capture_state_ == tab_capture::TAB_CAPTURE_STATE_ACTIVE)
111 registry_->DispatchStatusChangeEvent(this);
112 }
113
114 virtual void DidToggleFullscreenModeForTab(bool entered_fullscreen) OVERRIDE {
115 is_fullscreened_ = entered_fullscreen;
116 if (capture_state_ == tab_capture::TAB_CAPTURE_STATE_ACTIVE)
117 registry_->DispatchStatusChangeEvent(this);
118 }
119
120 virtual void WebContentsDestroyed() OVERRIDE {
121 registry_->KillRequest(this); // Deletes |this|.
122 }
34 123
35 private: 124 private:
36 // content::WebContentsObserver implementation. 125 const std::string extension_id_;
37 virtual void DidShowFullscreenWidget(int routing_id) OVERRIDE; 126 TabCaptureRegistry* const registry_;
38 virtual void DidDestroyFullscreenWidget(int routing_id) OVERRIDE; 127 TabCaptureState capture_state_;
128 bool is_verified_;
129 bool is_fullscreened_;
39 130
40 TabCaptureRequest* request_; 131 // These reference the originally targetted RenderFrameHost by its ID. The
41 const TabCaptureRegistry* registry_; 132 // RenderFrameHost may have gone away long before a LiveRequest closes, but
133 // calls to OnRequestUpdate() will always refer to this request by this ID.
134 int render_process_id_;
135 int render_frame_id_;
42 136
43 DISALLOW_COPY_AND_ASSIGN(FullscreenObserver); 137 DISALLOW_COPY_AND_ASSIGN(LiveRequest);
44 }; 138 };
45 139
46 // Holds all the state related to a tab capture stream.
47 struct TabCaptureRequest {
48 TabCaptureRequest(int render_process_id,
49 int render_view_id,
50 const std::string& extension_id,
51 int tab_id,
52 TabCaptureState status);
53 ~TabCaptureRequest();
54
55 const int render_process_id;
56 const int render_view_id;
57 const std::string extension_id;
58 const int tab_id;
59 TabCaptureState status;
60 TabCaptureState last_status;
61 bool fullscreen;
62 scoped_ptr<FullscreenObserver> fullscreen_observer;
63 };
64
65 FullscreenObserver::FullscreenObserver(
66 TabCaptureRequest* request,
67 const TabCaptureRegistry* registry)
68 : request_(request),
69 registry_(registry) {
70 content::RenderViewHost* const rvh =
71 content::RenderViewHost::FromID(request->render_process_id,
72 request->render_view_id);
73 Observe(rvh ? content::WebContents::FromRenderViewHost(rvh) : NULL);
74 }
75
76 void FullscreenObserver::DidShowFullscreenWidget(
77 int routing_id) {
78 request_->fullscreen = true;
79 registry_->DispatchStatusChangeEvent(request_);
80 }
81
82 void FullscreenObserver::DidDestroyFullscreenWidget(
83 int routing_id) {
84 request_->fullscreen = false;
85 registry_->DispatchStatusChangeEvent(request_);
86 }
87
88 TabCaptureRequest::TabCaptureRequest(
89 int render_process_id,
90 int render_view_id,
91 const std::string& extension_id,
92 const int tab_id,
93 TabCaptureState status)
94 : render_process_id(render_process_id),
95 render_view_id(render_view_id),
96 extension_id(extension_id),
97 tab_id(tab_id),
98 status(status),
99 last_status(status),
100 fullscreen(false) {
101 }
102
103 TabCaptureRequest::~TabCaptureRequest() {
104 }
105
106 TabCaptureRegistry::TabCaptureRegistry(content::BrowserContext* context) 140 TabCaptureRegistry::TabCaptureRegistry(content::BrowserContext* context)
107 : browser_context_(context), extension_registry_observer_(this) { 141 : browser_context_(context), extension_registry_observer_(this) {
108 MediaCaptureDevicesDispatcher::GetInstance()->AddObserver(this); 142 MediaCaptureDevicesDispatcher::GetInstance()->AddObserver(this);
109 registrar_.Add(this,
110 chrome::NOTIFICATION_FULLSCREEN_CHANGED,
111 content::NotificationService::AllSources());
112 extension_registry_observer_.Add(ExtensionRegistry::Get(browser_context_)); 143 extension_registry_observer_.Add(ExtensionRegistry::Get(browser_context_));
113 } 144 }
114 145
115 TabCaptureRegistry::~TabCaptureRegistry() { 146 TabCaptureRegistry::~TabCaptureRegistry() {
116 MediaCaptureDevicesDispatcher::GetInstance()->RemoveObserver(this); 147 MediaCaptureDevicesDispatcher::GetInstance()->RemoveObserver(this);
117 } 148 }
118 149
119 // static 150 // static
120 TabCaptureRegistry* TabCaptureRegistry::Get(content::BrowserContext* context) { 151 TabCaptureRegistry* TabCaptureRegistry::Get(content::BrowserContext* context) {
121 return BrowserContextKeyedAPIFactory<TabCaptureRegistry>::Get(context); 152 return BrowserContextKeyedAPIFactory<TabCaptureRegistry>::Get(context);
122 } 153 }
123 154
124 static base::LazyInstance<BrowserContextKeyedAPIFactory<TabCaptureRegistry> > 155 static base::LazyInstance<BrowserContextKeyedAPIFactory<TabCaptureRegistry> >
125 g_factory = LAZY_INSTANCE_INITIALIZER; 156 g_factory = LAZY_INSTANCE_INITIALIZER;
126 157
127 // static 158 // static
128 BrowserContextKeyedAPIFactory<TabCaptureRegistry>* 159 BrowserContextKeyedAPIFactory<TabCaptureRegistry>*
129 TabCaptureRegistry::GetFactoryInstance() { 160 TabCaptureRegistry::GetFactoryInstance() {
130 return g_factory.Pointer(); 161 return g_factory.Pointer();
131 } 162 }
132 163
133 const TabCaptureRegistry::RegistryCaptureInfo 164 void TabCaptureRegistry::GetCapturedTabs(
134 TabCaptureRegistry::GetCapturedTabs(const std::string& extension_id) const { 165 const std::string& extension_id,
166 base::ListValue* list_of_capture_info) const {
135 DCHECK_CURRENTLY_ON(BrowserThread::UI); 167 DCHECK_CURRENTLY_ON(BrowserThread::UI);
136 RegistryCaptureInfo list; 168 DCHECK(list_of_capture_info);
137 for (ScopedVector<TabCaptureRequest>::const_iterator it = requests_.begin(); 169 list_of_capture_info->Clear();
170 for (ScopedVector<LiveRequest>::const_iterator it = requests_.begin();
138 it != requests_.end(); ++it) { 171 it != requests_.end(); ++it) {
139 if ((*it)->extension_id == extension_id) { 172 if ((*it)->is_verified() && (*it)->extension_id() == extension_id) {
140 list.push_back(std::make_pair((*it)->tab_id, (*it)->status)); 173 tab_capture::CaptureInfo info;
141 } 174 (*it)->GetCaptureInfo(&info);
142 } 175 list_of_capture_info->Append(info.ToValue().release());
143 return list;
144 }
145
146 void TabCaptureRegistry::Observe(int type,
147 const content::NotificationSource& source,
148 const content::NotificationDetails& details) {
149 DCHECK_CURRENTLY_ON(BrowserThread::UI);
150 DCHECK_EQ(chrome::NOTIFICATION_FULLSCREEN_CHANGED, type);
151 FullscreenController* fullscreen_controller =
152 content::Source<FullscreenController>(source).ptr();
153 const bool is_fullscreen = *content::Details<bool>(details).ptr();
154 for (ScopedVector<TabCaptureRequest>::iterator it = requests_.begin();
155 it != requests_.end();
156 ++it) {
157 // If we are exiting fullscreen mode, we only need to check if any of
158 // the requests had the fullscreen flag toggled previously. The
159 // fullscreen controller no longer has the reference to the fullscreen
160 // web_contents here.
161 if (!is_fullscreen) {
162 if ((*it)->fullscreen) {
163 (*it)->fullscreen = false;
164 DispatchStatusChangeEvent(*it);
165 break;
166 }
167 continue;
168 }
169
170 // If we are entering fullscreen mode, find whether the web_contents we
171 // are capturing entered fullscreen mode.
172 content::RenderViewHost* const rvh = content::RenderViewHost::FromID(
173 (*it)->render_process_id, (*it)->render_view_id);
174 if (rvh &&
175 fullscreen_controller->IsFullscreenForTabOrPending(
176 content::WebContents::FromRenderViewHost(rvh))) {
177 (*it)->fullscreen = true;
178 DispatchStatusChangeEvent(*it);
179 break;
180 } 176 }
181 } 177 }
182 } 178 }
183 179
184 void TabCaptureRegistry::OnExtensionUnloaded( 180 void TabCaptureRegistry::OnExtensionUnloaded(
185 content::BrowserContext* browser_context, 181 content::BrowserContext* browser_context,
186 const Extension* extension, 182 const Extension* extension,
187 UnloadedExtensionInfo::Reason reason) { 183 UnloadedExtensionInfo::Reason reason) {
188 // Cleanup all the requested media streams for this extension. 184 // Cleanup all the requested media streams for this extension.
189 for (ScopedVector<TabCaptureRequest>::iterator it = requests_.begin(); 185 for (ScopedVector<LiveRequest>::iterator it = requests_.begin();
190 it != requests_.end();) { 186 it != requests_.end();) {
191 if ((*it)->extension_id == extension->id()) { 187 if ((*it)->extension_id() == extension->id()) {
192 it = requests_.erase(it); 188 it = requests_.erase(it);
193 } else { 189 } else {
194 ++it; 190 ++it;
195 } 191 }
196 } 192 }
197 } 193 }
198 194
199 bool TabCaptureRegistry::AddRequest(int render_process_id, 195 bool TabCaptureRegistry::AddRequest(content::WebContents* target_contents,
200 int render_view_id, 196 const std::string& extension_id) {
201 const std::string& extension_id, 197 LiveRequest* const request = FindRequest(target_contents);
202 int tab_id, 198
203 TabCaptureState status) {
204 TabCaptureRequest* request = FindCaptureRequest(render_process_id,
205 render_view_id);
206 // Currently, we do not allow multiple active captures for same tab. 199 // Currently, we do not allow multiple active captures for same tab.
207 if (request != NULL) { 200 if (request != NULL) {
208 if (request->status != tab_capture::TAB_CAPTURE_STATE_STOPPED && 201 if (request->capture_state() != tab_capture::TAB_CAPTURE_STATE_STOPPED &&
209 request->status != tab_capture::TAB_CAPTURE_STATE_ERROR) { 202 request->capture_state() != tab_capture::TAB_CAPTURE_STATE_ERROR) {
210 return false; 203 return false;
211 } else { 204 } else {
212 DeleteCaptureRequest(render_process_id, render_view_id); 205 // Delete the request before creating its replacement (below).
206 KillRequest(request);
213 } 207 }
214 } 208 }
215 209
216 requests_.push_back(new TabCaptureRequest(render_process_id, 210 requests_.push_back(new LiveRequest(target_contents, extension_id, this));
217 render_view_id,
218 extension_id,
219 tab_id,
220 status));
221 return true; 211 return true;
222 } 212 }
223 213
224 bool TabCaptureRegistry::VerifyRequest(int render_process_id, 214 bool TabCaptureRegistry::VerifyRequest(
225 int render_view_id) { 215 int render_process_id,
216 int render_frame_id,
217 const std::string& extension_id) {
226 DCHECK_CURRENTLY_ON(BrowserThread::UI); 218 DCHECK_CURRENTLY_ON(BrowserThread::UI);
227 DVLOG(1) << "Verifying tabCapture request for " 219
228 << render_process_id << ":" << render_view_id; 220 LiveRequest* const request = FindRequest(
229 // TODO(justinlin): Verify extension too. 221 content::WebContents::FromRenderFrameHost(
230 return (FindCaptureRequest(render_process_id, render_view_id) != NULL); 222 content::RenderFrameHost::FromID(
223 render_process_id, render_frame_id)));
224 if (!request)
225 return false; // Unknown RenderFrameHost ID, or frame has gone away.
226
227 // TODO(miu): We should probably also verify the origin URL, like the desktop
228 // capture API. http://crbug.com/163100
229 if (request->is_verified() ||
230 request->extension_id() != extension_id ||
231 (request->capture_state() != tab_capture::TAB_CAPTURE_STATE_NONE &&
232 request->capture_state() != tab_capture::TAB_CAPTURE_STATE_PENDING))
233 return false;
234
235 // TODO(miu): The RenderFrameHost IDs should be set when LiveRequest is
236 // constructed, but ExtensionFunction does not yet support use of
237 // render_frame_host() to determine the exact RenderFrameHost for the call to
238 // AddRequest() above. Fix tab_capture_api.cc, and then fix this ugly hack.
239 // http://crbug.com/304341
240 request->SetOriginallyTargettedRenderFrameID(
241 render_process_id, render_frame_id);
242
243 request->SetIsVerified();
244 return true;
231 } 245 }
232 246
233 void TabCaptureRegistry::OnRequestUpdate( 247 void TabCaptureRegistry::OnRequestUpdate(
234 int render_process_id, 248 int original_target_render_process_id,
235 int render_view_id, 249 int original_target_render_frame_id,
236 const content::MediaStreamDevice& device, 250 content::MediaStreamType stream_type,
237 const content::MediaRequestState new_state) { 251 const content::MediaRequestState new_state) {
238 DCHECK_CURRENTLY_ON(BrowserThread::UI); 252 DCHECK_CURRENTLY_ON(BrowserThread::UI);
239 if (device.type != content::MEDIA_TAB_VIDEO_CAPTURE && 253 if (stream_type != content::MEDIA_TAB_VIDEO_CAPTURE &&
240 device.type != content::MEDIA_TAB_AUDIO_CAPTURE) { 254 stream_type != content::MEDIA_TAB_AUDIO_CAPTURE) {
241 return; 255 return;
242 } 256 }
243 257
244 TabCaptureRequest* request = FindCaptureRequest(render_process_id, 258 LiveRequest* request = FindRequest(original_target_render_process_id,
245 render_view_id); 259 original_target_render_frame_id);
246 if (request == NULL) { 260 if (!request) {
247 // TODO(justinlin): This can happen because the extension's renderer does 261 // Fall-back: Search again using WebContents since this method may have been
248 // not seem to always cleanup streams correctly. 262 // called before VerifyRequest() set the RenderFrameHost ID. If the
249 LOG(ERROR) << "Receiving updates for deleted capture request."; 263 // RenderFrameHost has gone away, that's okay since the upcoming call to
250 return; 264 // VerifyRequest() will fail, and that means the tracking of request updates
265 // doesn't matter anymore.
266 request = FindRequest(content::WebContents::FromRenderFrameHost(
267 content::RenderFrameHost::FromID(original_target_render_process_id,
268 original_target_render_frame_id)));
269 if (!request)
270 return; // Stale or invalid request update.
251 } 271 }
252 272
253 bool opening_stream = false;
254 bool stopping_stream = false;
255
256 TabCaptureState next_state = tab_capture::TAB_CAPTURE_STATE_NONE; 273 TabCaptureState next_state = tab_capture::TAB_CAPTURE_STATE_NONE;
257 switch (new_state) { 274 switch (new_state) {
258 case content::MEDIA_REQUEST_STATE_PENDING_APPROVAL: 275 case content::MEDIA_REQUEST_STATE_PENDING_APPROVAL:
259 next_state = tab_capture::TAB_CAPTURE_STATE_PENDING; 276 next_state = tab_capture::TAB_CAPTURE_STATE_PENDING;
260 break; 277 break;
261 case content::MEDIA_REQUEST_STATE_DONE: 278 case content::MEDIA_REQUEST_STATE_DONE:
262 opening_stream = true;
263 next_state = tab_capture::TAB_CAPTURE_STATE_ACTIVE; 279 next_state = tab_capture::TAB_CAPTURE_STATE_ACTIVE;
264 break; 280 break;
265 case content::MEDIA_REQUEST_STATE_CLOSING: 281 case content::MEDIA_REQUEST_STATE_CLOSING:
266 stopping_stream = true;
267 next_state = tab_capture::TAB_CAPTURE_STATE_STOPPED; 282 next_state = tab_capture::TAB_CAPTURE_STATE_STOPPED;
268 break; 283 break;
269 case content::MEDIA_REQUEST_STATE_ERROR: 284 case content::MEDIA_REQUEST_STATE_ERROR:
270 stopping_stream = true;
271 next_state = tab_capture::TAB_CAPTURE_STATE_ERROR; 285 next_state = tab_capture::TAB_CAPTURE_STATE_ERROR;
272 break; 286 break;
273 case content::MEDIA_REQUEST_STATE_OPENING: 287 case content::MEDIA_REQUEST_STATE_OPENING:
274 return; 288 return;
275 case content::MEDIA_REQUEST_STATE_REQUESTED: 289 case content::MEDIA_REQUEST_STATE_REQUESTED:
276 case content::MEDIA_REQUEST_STATE_NOT_REQUESTED: 290 case content::MEDIA_REQUEST_STATE_NOT_REQUESTED:
277 NOTREACHED(); 291 NOTREACHED();
278 return; 292 return;
279 } 293 }
280 294
281 if (next_state == tab_capture::TAB_CAPTURE_STATE_PENDING && 295 if (next_state == tab_capture::TAB_CAPTURE_STATE_PENDING &&
282 request->status != tab_capture::TAB_CAPTURE_STATE_PENDING && 296 request->capture_state() != tab_capture::TAB_CAPTURE_STATE_PENDING &&
283 request->status != tab_capture::TAB_CAPTURE_STATE_NONE && 297 request->capture_state() != tab_capture::TAB_CAPTURE_STATE_NONE &&
284 request->status != tab_capture::TAB_CAPTURE_STATE_STOPPED && 298 request->capture_state() != tab_capture::TAB_CAPTURE_STATE_STOPPED &&
285 request->status != tab_capture::TAB_CAPTURE_STATE_ERROR) { 299 request->capture_state() != tab_capture::TAB_CAPTURE_STATE_ERROR) {
286 // If we end up trying to grab a new stream while the previous one was never 300 // If we end up trying to grab a new stream while the previous one was never
287 // terminated, then something fishy is going on. 301 // terminated, then something fishy is going on.
288 NOTREACHED() << "Trying to capture tab with existing stream."; 302 NOTREACHED() << "Trying to capture tab with existing stream.";
289 return; 303 return;
290 } 304 }
291 305
292 if (opening_stream) { 306 request->UpdateCaptureState(next_state);
293 request->fullscreen_observer.reset(new FullscreenObserver(request, this));
294 }
295
296 if (stopping_stream) {
297 request->fullscreen_observer.reset();
298 }
299
300 request->last_status = request->status;
301 request->status = next_state;
302
303 // We will get duplicate events if we requested both audio and video, so only
304 // send new events.
305 if (request->last_status != request->status) {
306 DispatchStatusChangeEvent(request);
307 }
308 } 307 }
309 308
310 void TabCaptureRegistry::DispatchStatusChangeEvent( 309 void TabCaptureRegistry::DispatchStatusChangeEvent(
311 const TabCaptureRequest* request) const { 310 const LiveRequest* request) const {
312 EventRouter* router = EventRouter::Get(browser_context_); 311 EventRouter* router = EventRouter::Get(browser_context_);
313 if (!router) 312 if (!router)
314 return; 313 return;
315 314
316 scoped_ptr<tab_capture::CaptureInfo> info(new tab_capture::CaptureInfo());
317 info->tab_id = request->tab_id;
318 info->status = request->status;
319 info->fullscreen = request->fullscreen;
320
321 scoped_ptr<base::ListValue> args(new base::ListValue()); 315 scoped_ptr<base::ListValue> args(new base::ListValue());
322 args->Append(info->ToValue().release()); 316 tab_capture::CaptureInfo info;
317 request->GetCaptureInfo(&info);
318 args->Append(info.ToValue().release());
323 scoped_ptr<Event> event(new Event(tab_capture::OnStatusChanged::kEventName, 319 scoped_ptr<Event> event(new Event(tab_capture::OnStatusChanged::kEventName,
324 args.Pass())); 320 args.Pass()));
325 event->restrict_to_browser_context = browser_context_; 321 event->restrict_to_browser_context = browser_context_;
326 322
327 router->DispatchEventToExtension(request->extension_id, event.Pass()); 323 router->DispatchEventToExtension(request->extension_id(), event.Pass());
328 } 324 }
329 325
330 TabCaptureRequest* TabCaptureRegistry::FindCaptureRequest( 326 TabCaptureRegistry::LiveRequest* TabCaptureRegistry::FindRequest(
331 int render_process_id, int render_view_id) const { 327 const content::WebContents* target_contents) const {
332 for (ScopedVector<TabCaptureRequest>::const_iterator it = requests_.begin(); 328 for (ScopedVector<LiveRequest>::const_iterator it = requests_.begin();
333 it != requests_.end(); ++it) { 329 it != requests_.end(); ++it) {
334 if ((*it)->render_process_id == render_process_id && 330 if ((*it)->target_contents() == target_contents)
335 (*it)->render_view_id == render_view_id) {
336 return *it; 331 return *it;
337 }
338 } 332 }
339 return NULL; 333 return NULL;
340 } 334 }
341 335
342 void TabCaptureRegistry::DeleteCaptureRequest(int render_process_id, 336 TabCaptureRegistry::LiveRequest* TabCaptureRegistry::FindRequest(
343 int render_view_id) { 337 int original_target_render_process_id,
344 for (ScopedVector<TabCaptureRequest>::iterator it = requests_.begin(); 338 int original_target_render_frame_id) const {
339 for (ScopedVector<LiveRequest>::const_iterator it = requests_.begin();
345 it != requests_.end(); ++it) { 340 it != requests_.end(); ++it) {
346 if ((*it)->render_process_id == render_process_id && 341 if ((*it)->WasOriginallyTargettingRenderFrameID(
347 (*it)->render_view_id == render_view_id) { 342 original_target_render_process_id,
343 original_target_render_frame_id))
344 return *it;
345 }
346 return NULL;
347 }
348
349 void TabCaptureRegistry::KillRequest(LiveRequest* request) {
350 for (ScopedVector<LiveRequest>::iterator it = requests_.begin();
351 it != requests_.end(); ++it) {
352 if ((*it) == request) {
348 requests_.erase(it); 353 requests_.erase(it);
349 return; 354 return;
350 } 355 }
351 } 356 }
357 NOTREACHED();
352 } 358 }
353 359
354 } // namespace extensions 360 } // namespace extensions
OLDNEW
« no previous file with comments | « chrome/browser/extensions/api/tab_capture/tab_capture_registry.h ('k') | chrome/browser/media/desktop_streams_registry.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698