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/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 // TODO(miu): This initial value for |is_fullscreened_| is a faulty | |
39 // assumption. http://crbug.com/350491 | |
40 is_fullscreened_(false) { | |
41 DCHECK(web_contents()); | |
42 DCHECK(registry_); | |
43 } | |
44 | |
45 virtual ~LiveRequest() {} | |
46 | |
47 // Accessors. | |
48 const content::WebContents* target_contents() const { | |
49 return content::WebContentsObserver::web_contents(); | |
50 } | |
51 const std::string& extension_id() const { | |
52 return extension_id_; | |
53 } | |
54 TabCaptureState capture_state() const { | |
55 return capture_state_; | |
56 } | |
57 | |
58 void UpdateCaptureState(TabCaptureState next_capture_state) { | |
59 // This method can get duplicate calls if both audio and video were | |
60 // requested, so return early to avoid duplicate dispatching of status | |
61 // change events. | |
62 if (capture_state_ == next_capture_state) | |
63 return; | |
64 | |
65 capture_state_ = next_capture_state; | |
66 registry_->DispatchStatusChangeEvent(this); | |
67 } | |
68 | |
69 void GetCaptureInfo(tab_capture::CaptureInfo* info) const { | |
70 info->tab_id = SessionID::IdForTab(web_contents()); | |
71 info->status = capture_state_; | |
72 info->fullscreen = is_fullscreened_; | |
73 } | |
74 | |
75 protected: | |
76 virtual void DidShowFullscreenWidget(int routing_id) OVERRIDE { | |
77 is_fullscreened_ = true; | |
78 if (capture_state_ == tab_capture::TAB_CAPTURE_STATE_ACTIVE) | |
79 registry_->DispatchStatusChangeEvent(this); | |
80 } | |
81 | |
82 virtual void DidDestroyFullscreenWidget(int routing_id) OVERRIDE { | |
83 is_fullscreened_ = false; | |
84 if (capture_state_ == tab_capture::TAB_CAPTURE_STATE_ACTIVE) | |
85 registry_->DispatchStatusChangeEvent(this); | |
86 } | |
87 | |
88 virtual void DidToggleFullscreenModeForTab(bool entered_fullscreen) OVERRIDE { | |
89 is_fullscreened_ = entered_fullscreen; | |
90 if (capture_state_ == tab_capture::TAB_CAPTURE_STATE_ACTIVE) | |
91 registry_->DispatchStatusChangeEvent(this); | |
92 } | |
93 | |
94 virtual void WebContentsDestroyed() OVERRIDE { | |
95 registry_->KillRequest(this); // Deletes |this|. | |
96 } | |
34 | 97 |
35 private: | 98 private: |
36 // content::WebContentsObserver implementation. | 99 const std::string extension_id_; |
37 virtual void DidShowFullscreenWidget(int routing_id) OVERRIDE; | 100 TabCaptureRegistry* const registry_; |
38 virtual void DidDestroyFullscreenWidget(int routing_id) OVERRIDE; | 101 TabCaptureState capture_state_; |
102 bool is_fullscreened_; | |
39 | 103 |
40 TabCaptureRequest* request_; | 104 DISALLOW_COPY_AND_ASSIGN(LiveRequest); |
41 const TabCaptureRegistry* registry_; | |
42 | |
43 DISALLOW_COPY_AND_ASSIGN(FullscreenObserver); | |
44 }; | 105 }; |
45 | 106 |
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) | 107 TabCaptureRegistry::TabCaptureRegistry(content::BrowserContext* context) |
107 : browser_context_(context), extension_registry_observer_(this) { | 108 : browser_context_(context), extension_registry_observer_(this) { |
108 MediaCaptureDevicesDispatcher::GetInstance()->AddObserver(this); | 109 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_)); | 110 extension_registry_observer_.Add(ExtensionRegistry::Get(browser_context_)); |
113 } | 111 } |
114 | 112 |
115 TabCaptureRegistry::~TabCaptureRegistry() { | 113 TabCaptureRegistry::~TabCaptureRegistry() { |
116 MediaCaptureDevicesDispatcher::GetInstance()->RemoveObserver(this); | 114 MediaCaptureDevicesDispatcher::GetInstance()->RemoveObserver(this); |
117 } | 115 } |
118 | 116 |
119 // static | 117 // static |
120 TabCaptureRegistry* TabCaptureRegistry::Get(content::BrowserContext* context) { | 118 TabCaptureRegistry* TabCaptureRegistry::Get(content::BrowserContext* context) { |
121 return BrowserContextKeyedAPIFactory<TabCaptureRegistry>::Get(context); | 119 return BrowserContextKeyedAPIFactory<TabCaptureRegistry>::Get(context); |
122 } | 120 } |
123 | 121 |
124 static base::LazyInstance<BrowserContextKeyedAPIFactory<TabCaptureRegistry> > | 122 static base::LazyInstance<BrowserContextKeyedAPIFactory<TabCaptureRegistry> > |
125 g_factory = LAZY_INSTANCE_INITIALIZER; | 123 g_factory = LAZY_INSTANCE_INITIALIZER; |
126 | 124 |
127 // static | 125 // static |
128 BrowserContextKeyedAPIFactory<TabCaptureRegistry>* | 126 BrowserContextKeyedAPIFactory<TabCaptureRegistry>* |
129 TabCaptureRegistry::GetFactoryInstance() { | 127 TabCaptureRegistry::GetFactoryInstance() { |
130 return g_factory.Pointer(); | 128 return g_factory.Pointer(); |
131 } | 129 } |
132 | 130 |
133 const TabCaptureRegistry::RegistryCaptureInfo | 131 void TabCaptureRegistry::GetCapturedTabs( |
134 TabCaptureRegistry::GetCapturedTabs(const std::string& extension_id) const { | 132 const std::string& extension_id, |
133 base::ListValue* list_of_capture_info) const { | |
135 DCHECK_CURRENTLY_ON(BrowserThread::UI); | 134 DCHECK_CURRENTLY_ON(BrowserThread::UI); |
136 RegistryCaptureInfo list; | 135 DCHECK(list_of_capture_info); |
137 for (ScopedVector<TabCaptureRequest>::const_iterator it = requests_.begin(); | 136 list_of_capture_info->Clear(); |
137 for (ScopedVector<LiveRequest>::const_iterator it = requests_.begin(); | |
138 it != requests_.end(); ++it) { | 138 it != requests_.end(); ++it) { |
139 if ((*it)->extension_id == extension_id) { | 139 if ((*it)->extension_id() == extension_id) { |
140 list.push_back(std::make_pair((*it)->tab_id, (*it)->status)); | 140 tab_capture::CaptureInfo info; |
141 } | 141 (*it)->GetCaptureInfo(&info); |
142 } | 142 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 } | 143 } |
181 } | 144 } |
182 } | 145 } |
183 | 146 |
184 void TabCaptureRegistry::OnExtensionUnloaded( | 147 void TabCaptureRegistry::OnExtensionUnloaded( |
185 content::BrowserContext* browser_context, | 148 content::BrowserContext* browser_context, |
186 const Extension* extension, | 149 const Extension* extension, |
187 UnloadedExtensionInfo::Reason reason) { | 150 UnloadedExtensionInfo::Reason reason) { |
188 // Cleanup all the requested media streams for this extension. | 151 // Cleanup all the requested media streams for this extension. |
189 for (ScopedVector<TabCaptureRequest>::iterator it = requests_.begin(); | 152 for (ScopedVector<LiveRequest>::iterator it = requests_.begin(); |
190 it != requests_.end();) { | 153 it != requests_.end();) { |
191 if ((*it)->extension_id == extension->id()) { | 154 if ((*it)->extension_id() == extension->id()) { |
192 it = requests_.erase(it); | 155 it = requests_.erase(it); |
193 } else { | 156 } else { |
194 ++it; | 157 ++it; |
195 } | 158 } |
196 } | 159 } |
197 } | 160 } |
198 | 161 |
199 bool TabCaptureRegistry::AddRequest(int render_process_id, | 162 bool TabCaptureRegistry::AddRequest(content::WebContents* target_contents, |
200 int render_view_id, | 163 const std::string& extension_id) { |
201 const std::string& extension_id, | 164 LiveRequest* const request = FindRequest(target_contents); |
202 int tab_id, | 165 |
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. | 166 // Currently, we do not allow multiple active captures for same tab. |
207 if (request != NULL) { | 167 if (request != NULL) { |
208 if (request->status != tab_capture::TAB_CAPTURE_STATE_STOPPED && | 168 if (request->capture_state() != tab_capture::TAB_CAPTURE_STATE_STOPPED && |
209 request->status != tab_capture::TAB_CAPTURE_STATE_ERROR) { | 169 request->capture_state() != tab_capture::TAB_CAPTURE_STATE_ERROR) { |
210 return false; | 170 return false; |
211 } else { | 171 } else { |
212 DeleteCaptureRequest(render_process_id, render_view_id); | 172 // Delete the request before creating its replacement (below). |
173 KillRequest(request); | |
213 } | 174 } |
214 } | 175 } |
215 | 176 |
216 requests_.push_back(new TabCaptureRequest(render_process_id, | 177 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; | 178 return true; |
222 } | 179 } |
223 | 180 |
224 bool TabCaptureRegistry::VerifyRequest(int render_process_id, | 181 bool TabCaptureRegistry::VerifyRequest( |
225 int render_view_id) { | 182 const content::WebContents* target_contents, |
183 const std::string& extension_id) { | |
226 DCHECK_CURRENTLY_ON(BrowserThread::UI); | 184 DCHECK_CURRENTLY_ON(BrowserThread::UI); |
227 DVLOG(1) << "Verifying tabCapture request for " | 185 LiveRequest* const request = FindRequest(target_contents); |
228 << render_process_id << ":" << render_view_id; | 186 // TODO(miu): We should probably also verify the origin URL, like the desktop |
229 // TODO(justinlin): Verify extension too. | 187 // capture API. http://crbug.com/163100 |
230 return (FindCaptureRequest(render_process_id, render_view_id) != NULL); | 188 return request && request->extension_id() == extension_id && |
189 (request->capture_state() == tab_capture::TAB_CAPTURE_STATE_NONE || | |
190 request->capture_state() == tab_capture::TAB_CAPTURE_STATE_PENDING); | |
231 } | 191 } |
232 | 192 |
233 void TabCaptureRegistry::OnRequestUpdate( | 193 void TabCaptureRegistry::OnRequestUpdate( |
234 int render_process_id, | 194 int render_process_id, |
235 int render_view_id, | 195 int render_frame_id, |
236 const content::MediaStreamDevice& device, | 196 content::MediaStreamType stream_type, |
237 const content::MediaRequestState new_state) { | 197 const content::MediaRequestState new_state) { |
238 DCHECK_CURRENTLY_ON(BrowserThread::UI); | 198 DCHECK_CURRENTLY_ON(BrowserThread::UI); |
239 if (device.type != content::MEDIA_TAB_VIDEO_CAPTURE && | 199 if (stream_type != content::MEDIA_TAB_VIDEO_CAPTURE && |
240 device.type != content::MEDIA_TAB_AUDIO_CAPTURE) { | 200 stream_type != content::MEDIA_TAB_AUDIO_CAPTURE) { |
241 return; | 201 return; |
242 } | 202 } |
243 | 203 |
244 TabCaptureRequest* request = FindCaptureRequest(render_process_id, | 204 LiveRequest* const request = FindRequest( |
245 render_view_id); | 205 content::WebContents::FromRenderFrameHost( |
246 if (request == NULL) { | 206 content::RenderFrameHost::FromID( |
247 // TODO(justinlin): This can happen because the extension's renderer does | 207 render_process_id, render_frame_id))); |
ncarter (slow)
2014/07/11 22:32:24
Before this change, it seems that the original ID
miu
2014/07/12 03:16:29
I was able to confirm, as you feared, that this is
| |
248 // not seem to always cleanup streams correctly. | 208 if (request == NULL) |
249 LOG(ERROR) << "Receiving updates for deleted capture request."; | 209 return; // Stale or invalid request update. |
250 return; | |
251 } | |
252 | |
253 bool opening_stream = false; | |
254 bool stopping_stream = false; | |
255 | 210 |
256 TabCaptureState next_state = tab_capture::TAB_CAPTURE_STATE_NONE; | 211 TabCaptureState next_state = tab_capture::TAB_CAPTURE_STATE_NONE; |
257 switch (new_state) { | 212 switch (new_state) { |
258 case content::MEDIA_REQUEST_STATE_PENDING_APPROVAL: | 213 case content::MEDIA_REQUEST_STATE_PENDING_APPROVAL: |
259 next_state = tab_capture::TAB_CAPTURE_STATE_PENDING; | 214 next_state = tab_capture::TAB_CAPTURE_STATE_PENDING; |
260 break; | 215 break; |
261 case content::MEDIA_REQUEST_STATE_DONE: | 216 case content::MEDIA_REQUEST_STATE_DONE: |
262 opening_stream = true; | |
263 next_state = tab_capture::TAB_CAPTURE_STATE_ACTIVE; | 217 next_state = tab_capture::TAB_CAPTURE_STATE_ACTIVE; |
264 break; | 218 break; |
265 case content::MEDIA_REQUEST_STATE_CLOSING: | 219 case content::MEDIA_REQUEST_STATE_CLOSING: |
266 stopping_stream = true; | |
267 next_state = tab_capture::TAB_CAPTURE_STATE_STOPPED; | 220 next_state = tab_capture::TAB_CAPTURE_STATE_STOPPED; |
268 break; | 221 break; |
269 case content::MEDIA_REQUEST_STATE_ERROR: | 222 case content::MEDIA_REQUEST_STATE_ERROR: |
270 stopping_stream = true; | |
271 next_state = tab_capture::TAB_CAPTURE_STATE_ERROR; | 223 next_state = tab_capture::TAB_CAPTURE_STATE_ERROR; |
272 break; | 224 break; |
273 case content::MEDIA_REQUEST_STATE_OPENING: | 225 case content::MEDIA_REQUEST_STATE_OPENING: |
274 return; | 226 return; |
275 case content::MEDIA_REQUEST_STATE_REQUESTED: | 227 case content::MEDIA_REQUEST_STATE_REQUESTED: |
276 case content::MEDIA_REQUEST_STATE_NOT_REQUESTED: | 228 case content::MEDIA_REQUEST_STATE_NOT_REQUESTED: |
277 NOTREACHED(); | 229 NOTREACHED(); |
278 return; | 230 return; |
279 } | 231 } |
280 | 232 |
281 if (next_state == tab_capture::TAB_CAPTURE_STATE_PENDING && | 233 if (next_state == tab_capture::TAB_CAPTURE_STATE_PENDING && |
282 request->status != tab_capture::TAB_CAPTURE_STATE_PENDING && | 234 request->capture_state() != tab_capture::TAB_CAPTURE_STATE_PENDING && |
283 request->status != tab_capture::TAB_CAPTURE_STATE_NONE && | 235 request->capture_state() != tab_capture::TAB_CAPTURE_STATE_NONE && |
284 request->status != tab_capture::TAB_CAPTURE_STATE_STOPPED && | 236 request->capture_state() != tab_capture::TAB_CAPTURE_STATE_STOPPED && |
285 request->status != tab_capture::TAB_CAPTURE_STATE_ERROR) { | 237 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 | 238 // If we end up trying to grab a new stream while the previous one was never |
287 // terminated, then something fishy is going on. | 239 // terminated, then something fishy is going on. |
288 NOTREACHED() << "Trying to capture tab with existing stream."; | 240 NOTREACHED() << "Trying to capture tab with existing stream."; |
289 return; | 241 return; |
290 } | 242 } |
291 | 243 |
292 if (opening_stream) { | 244 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 } | 245 } |
309 | 246 |
310 void TabCaptureRegistry::DispatchStatusChangeEvent( | 247 void TabCaptureRegistry::DispatchStatusChangeEvent( |
311 const TabCaptureRequest* request) const { | 248 const LiveRequest* request) const { |
312 EventRouter* router = EventRouter::Get(browser_context_); | 249 EventRouter* router = EventRouter::Get(browser_context_); |
313 if (!router) | 250 if (!router) |
314 return; | 251 return; |
315 | 252 |
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()); | 253 scoped_ptr<base::ListValue> args(new base::ListValue()); |
322 args->Append(info->ToValue().release()); | 254 tab_capture::CaptureInfo info; |
255 request->GetCaptureInfo(&info); | |
256 args->Append(info.ToValue().release()); | |
323 scoped_ptr<Event> event(new Event(tab_capture::OnStatusChanged::kEventName, | 257 scoped_ptr<Event> event(new Event(tab_capture::OnStatusChanged::kEventName, |
324 args.Pass())); | 258 args.Pass())); |
325 event->restrict_to_browser_context = browser_context_; | 259 event->restrict_to_browser_context = browser_context_; |
326 | 260 |
327 router->DispatchEventToExtension(request->extension_id, event.Pass()); | 261 router->DispatchEventToExtension(request->extension_id(), event.Pass()); |
328 } | 262 } |
329 | 263 |
330 TabCaptureRequest* TabCaptureRegistry::FindCaptureRequest( | 264 TabCaptureRegistry::LiveRequest* TabCaptureRegistry::FindRequest( |
331 int render_process_id, int render_view_id) const { | 265 const content::WebContents* target_contents) const { |
332 for (ScopedVector<TabCaptureRequest>::const_iterator it = requests_.begin(); | 266 for (ScopedVector<LiveRequest>::const_iterator it = requests_.begin(); |
333 it != requests_.end(); ++it) { | 267 it != requests_.end(); ++it) { |
334 if ((*it)->render_process_id == render_process_id && | 268 if ((*it)->target_contents() == target_contents) |
335 (*it)->render_view_id == render_view_id) { | |
336 return *it; | 269 return *it; |
337 } | |
338 } | 270 } |
339 return NULL; | 271 return NULL; |
340 } | 272 } |
341 | 273 |
342 void TabCaptureRegistry::DeleteCaptureRequest(int render_process_id, | 274 void TabCaptureRegistry::KillRequest(LiveRequest* request) { |
343 int render_view_id) { | 275 for (ScopedVector<LiveRequest>::iterator it = requests_.begin(); |
344 for (ScopedVector<TabCaptureRequest>::iterator it = requests_.begin(); | |
345 it != requests_.end(); ++it) { | 276 it != requests_.end(); ++it) { |
346 if ((*it)->render_process_id == render_process_id && | 277 if ((*it) == request) { |
347 (*it)->render_view_id == render_view_id) { | |
348 requests_.erase(it); | 278 requests_.erase(it); |
349 return; | 279 return; |
350 } | 280 } |
351 } | 281 } |
282 NOTREACHED(); | |
352 } | 283 } |
353 | 284 |
354 } // namespace extensions | 285 } // namespace extensions |
OLD | NEW |