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 "content/public/browser/browser_thread.h" | 7 #include "content/public/browser/browser_thread.h" |
8 #include "chrome/browser/extensions/event_names.h" | 8 #include "chrome/browser/extensions/event_names.h" |
9 #include "chrome/browser/extensions/event_router.h" | 9 #include "chrome/browser/extensions/event_router.h" |
10 #include "chrome/browser/extensions/extension_system.h" | 10 #include "chrome/browser/extensions/extension_system.h" |
(...skipping 15 matching lines...) Expand all Loading... |
26 proxy_->Attach(this); | 26 proxy_->Attach(this); |
27 registrar_.Add(this, chrome::NOTIFICATION_EXTENSION_UNLOADED, | 27 registrar_.Add(this, chrome::NOTIFICATION_EXTENSION_UNLOADED, |
28 content::Source<Profile>(profile_)); | 28 content::Source<Profile>(profile_)); |
29 } | 29 } |
30 | 30 |
31 TabCaptureRegistry::~TabCaptureRegistry() { | 31 TabCaptureRegistry::~TabCaptureRegistry() { |
32 proxy_->Detach(); | 32 proxy_->Detach(); |
33 } | 33 } |
34 | 34 |
35 void TabCaptureRegistry::HandleRequestUpdateOnUIThread( | 35 void TabCaptureRegistry::HandleRequestUpdateOnUIThread( |
| 36 int render_process_id, |
| 37 int render_view_id, |
36 const content::MediaStreamDevice& device, | 38 const content::MediaStreamDevice& device, |
37 const content::MediaRequestState new_state) { | 39 const content::MediaRequestState new_state) { |
38 EventRouter* router = profile_ ? | 40 EventRouter* router = profile_ ? |
39 extensions::ExtensionSystem::Get(profile_)->event_router() : NULL; | 41 extensions::ExtensionSystem::Get(profile_)->event_router() : NULL; |
40 if (!router) | 42 if (!router) |
41 return; | 43 return; |
42 | 44 |
43 if (requests_.find(device.device_id) == requests_.end()) | 45 std::pair<int, int> key = std::make_pair(render_process_id, render_view_id); |
| 46 |
| 47 if (requests_.find(key) == requests_.end()) { |
| 48 LOG(ERROR) << "Receiving updates for invalid tab capture request."; |
44 return; | 49 return; |
| 50 } |
45 | 51 |
46 tab_capture::TabCaptureState state = | 52 tab_capture::TabCaptureState state = |
47 tab_capture::TAB_CAPTURE_TAB_CAPTURE_STATE_NONE; | 53 tab_capture::TAB_CAPTURE_TAB_CAPTURE_STATE_NONE; |
48 switch (new_state) { | 54 switch (new_state) { |
49 case content::MEDIA_REQUEST_STATE_REQUESTED: | 55 case content::MEDIA_REQUEST_STATE_REQUESTED: |
50 state = tab_capture::TAB_CAPTURE_TAB_CAPTURE_STATE_REQUESTED; | 56 state = tab_capture::TAB_CAPTURE_TAB_CAPTURE_STATE_REQUESTED; |
51 break; | 57 break; |
52 case content::MEDIA_REQUEST_STATE_PENDING_APPROVAL: | 58 case content::MEDIA_REQUEST_STATE_PENDING_APPROVAL: |
53 state = tab_capture::TAB_CAPTURE_TAB_CAPTURE_STATE_PENDING; | 59 state = tab_capture::TAB_CAPTURE_TAB_CAPTURE_STATE_PENDING; |
54 break; | 60 break; |
55 case content::MEDIA_REQUEST_STATE_DONE: | 61 case content::MEDIA_REQUEST_STATE_DONE: |
56 state = tab_capture::TAB_CAPTURE_TAB_CAPTURE_STATE_ACTIVE; | 62 state = tab_capture::TAB_CAPTURE_TAB_CAPTURE_STATE_ACTIVE; |
57 break; | 63 break; |
58 case content::MEDIA_REQUEST_STATE_CLOSING: | 64 case content::MEDIA_REQUEST_STATE_CLOSING: |
59 state = tab_capture::TAB_CAPTURE_TAB_CAPTURE_STATE_STOPPED; | 65 state = tab_capture::TAB_CAPTURE_TAB_CAPTURE_STATE_STOPPED; |
60 break; | 66 break; |
61 case content::MEDIA_REQUEST_STATE_ERROR: | 67 case content::MEDIA_REQUEST_STATE_ERROR: |
62 state = tab_capture::TAB_CAPTURE_TAB_CAPTURE_STATE_ERROR; | 68 state = tab_capture::TAB_CAPTURE_TAB_CAPTURE_STATE_ERROR; |
63 break; | 69 break; |
64 default: | 70 default: |
65 // TODO(justinlin): Implement muted state notification. | 71 // TODO(justinlin): Implement muted state notification. |
66 break; | 72 break; |
67 } | 73 } |
68 | 74 |
69 if (state == tab_capture::TAB_CAPTURE_TAB_CAPTURE_STATE_NONE) { | 75 if (state == tab_capture::TAB_CAPTURE_TAB_CAPTURE_STATE_NONE) { |
70 // This is a state we don't handle. | 76 // This is a state we don't handle. |
71 return; | 77 return; |
72 } | 78 } |
73 | 79 |
74 TabCaptureRegistry::TabCaptureRequest& request_info = | 80 TabCaptureRegistry::TabCaptureRequest& request_info = requests_[key]; |
75 requests_[device.device_id]; | |
76 request_info.status = state; | 81 request_info.status = state; |
77 | 82 |
78 scoped_ptr<tab_capture::CaptureInfo> info(new tab_capture::CaptureInfo()); | 83 scoped_ptr<tab_capture::CaptureInfo> info(new tab_capture::CaptureInfo()); |
79 info->tab_id = request_info.tab_id; | 84 info->tab_id = request_info.tab_id; |
80 info->status = request_info.status; | 85 info->status = request_info.status; |
81 | 86 |
82 scoped_ptr<base::ListValue> args(new ListValue()); | 87 scoped_ptr<base::ListValue> args(new ListValue()); |
83 args->Append(info->ToValue().release()); | 88 args->Append(info->ToValue().release()); |
84 scoped_ptr<Event> event(new Event( | 89 scoped_ptr<Event> event(new Event( |
85 events::kOnTabCaptureStatusChanged, args.Pass())); | 90 events::kOnTabCaptureStatusChanged, args.Pass())); |
(...skipping 29 matching lines...) Expand all Loading... |
115 requests_.erase(it++); | 120 requests_.erase(it++); |
116 } else { | 121 } else { |
117 ++it; | 122 ++it; |
118 } | 123 } |
119 } | 124 } |
120 break; | 125 break; |
121 } | 126 } |
122 } | 127 } |
123 } | 128 } |
124 | 129 |
125 bool TabCaptureRegistry::AddRequest( | 130 bool TabCaptureRegistry::AddRequest(const std::pair<int, int> key, |
126 const std::string& key, const TabCaptureRequest& request) { | 131 const TabCaptureRequest& request) { |
127 // Currently, we do not allow multiple active captures for same tab. | 132 // Currently, we do not allow multiple active captures for same tab. |
128 DCHECK(!key.empty()); | |
129 if (requests_.find(key) != requests_.end()) | 133 if (requests_.find(key) != requests_.end()) |
130 if (requests_[key].status != | 134 if (requests_[key].status != |
131 tab_capture::TAB_CAPTURE_TAB_CAPTURE_STATE_STOPPED && | 135 tab_capture::TAB_CAPTURE_TAB_CAPTURE_STATE_STOPPED && |
132 requests_[key].status != | 136 requests_[key].status != |
133 tab_capture::TAB_CAPTURE_TAB_CAPTURE_STATE_ERROR) | 137 tab_capture::TAB_CAPTURE_TAB_CAPTURE_STATE_ERROR) |
134 return false; | 138 return false; |
135 requests_[key] = request; | 139 requests_[key] = request; |
136 return true; | 140 return true; |
137 } | 141 } |
138 | 142 |
139 bool TabCaptureRegistry::VerifyRequest(const std::string& key) { | 143 bool TabCaptureRegistry::VerifyRequest(int render_process_id, |
140 return requests_.find(key) != requests_.end(); | 144 int render_view_id) { |
| 145 return requests_.find(std::make_pair( |
| 146 render_process_id, render_view_id)) != requests_.end(); |
141 } | 147 } |
142 | 148 |
143 void TabCaptureRegistry::MediaObserverProxy::Attach( | 149 void TabCaptureRegistry::MediaObserverProxy::Attach( |
144 TabCaptureRegistry* request_handler) { | 150 TabCaptureRegistry* request_handler) { |
145 handler_ = request_handler; | 151 handler_ = request_handler; |
146 BrowserThread::PostTask(BrowserThread::IO, FROM_HERE, | 152 BrowserThread::PostTask(BrowserThread::IO, FROM_HERE, |
147 base::Bind(&TabCaptureRegistry::MediaObserverProxy:: | 153 base::Bind(&TabCaptureRegistry::MediaObserverProxy:: |
148 RegisterAsMediaObserverOnIOThread, this, false)); | 154 RegisterAsMediaObserverOnIOThread, this, false)); |
149 } | 155 } |
150 | 156 |
151 void TabCaptureRegistry::MediaObserverProxy::Detach() { | 157 void TabCaptureRegistry::MediaObserverProxy::Detach() { |
152 handler_ = NULL; | 158 handler_ = NULL; |
153 BrowserThread::PostTask(BrowserThread::IO, FROM_HERE, | 159 BrowserThread::PostTask(BrowserThread::IO, FROM_HERE, |
154 base::Bind(&TabCaptureRegistry::MediaObserverProxy:: | 160 base::Bind(&TabCaptureRegistry::MediaObserverProxy:: |
155 RegisterAsMediaObserverOnIOThread, this, true)); | 161 RegisterAsMediaObserverOnIOThread, this, true)); |
156 } | 162 } |
157 | 163 |
158 void TabCaptureRegistry::MediaObserverProxy::RegisterAsMediaObserverOnIOThread( | 164 void TabCaptureRegistry::MediaObserverProxy::RegisterAsMediaObserverOnIOThread( |
159 bool unregister) { | 165 bool unregister) { |
160 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); | 166 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); |
161 if (MediaInternals::GetInstance()) { | 167 if (MediaInternals::GetInstance()) { |
162 if (!unregister) | 168 if (!unregister) |
163 MediaInternals::GetInstance()->AddObserver(this); | 169 MediaInternals::GetInstance()->AddObserver(this); |
164 else | 170 else |
165 MediaInternals::GetInstance()->RemoveObserver(this); | 171 MediaInternals::GetInstance()->RemoveObserver(this); |
166 } | 172 } |
167 } | 173 } |
168 | 174 |
169 void TabCaptureRegistry::MediaObserverProxy::OnRequestUpdate( | 175 void TabCaptureRegistry::MediaObserverProxy::OnRequestUpdate( |
| 176 int render_process_id, |
| 177 int render_view_id, |
170 const content::MediaStreamDevice& device, | 178 const content::MediaStreamDevice& device, |
171 const content::MediaRequestState new_state) { | 179 const content::MediaRequestState new_state) { |
172 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); | 180 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); |
173 | 181 |
174 // TODO(justinlin): We drop audio device events since they will occur in | 182 // TODO(justinlin): We drop audio device events since they will occur in |
175 // parallel with the video device events (we would get duplicate events). When | 183 // parallel with the video device events (we would get duplicate events). When |
176 // audio mirroring is implemented, we will want to grab those events when | 184 // audio mirroring is implemented, we will want to grab those events when |
177 // video is not requested. | 185 // video is not requested. |
178 if (device.type != content::MEDIA_TAB_VIDEO_CAPTURE) | 186 if (device.type != content::MEDIA_TAB_VIDEO_CAPTURE) |
179 return; | 187 return; |
180 | 188 |
181 BrowserThread::PostTask(BrowserThread::UI, FROM_HERE, | 189 BrowserThread::PostTask(BrowserThread::UI, FROM_HERE, |
182 base::Bind(&TabCaptureRegistry::MediaObserverProxy::UpdateOnUIThread, | 190 base::Bind(&TabCaptureRegistry::MediaObserverProxy::UpdateOnUIThread, |
183 this, device, new_state)); | 191 this, render_process_id, render_view_id, device, new_state)); |
184 } | 192 } |
185 | 193 |
186 void TabCaptureRegistry::MediaObserverProxy::UpdateOnUIThread( | 194 void TabCaptureRegistry::MediaObserverProxy::UpdateOnUIThread( |
| 195 int render_process_id, |
| 196 int render_view_id, |
187 const content::MediaStreamDevice& device, | 197 const content::MediaStreamDevice& device, |
188 const content::MediaRequestState new_state) { | 198 const content::MediaRequestState new_state) { |
189 if (handler_) | 199 if (handler_) |
190 handler_->HandleRequestUpdateOnUIThread(device, new_state); | 200 handler_->HandleRequestUpdateOnUIThread(render_process_id, |
| 201 render_view_id, |
| 202 device, |
| 203 new_state); |
191 } | 204 } |
192 | 205 |
193 } // namespace extensions | 206 } // namespace extensions |
OLD | NEW |