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/media/media_stream_capture_indicator.h" | 5 #include "chrome/browser/media/media_stream_capture_indicator.h" |
6 | 6 |
7 #include <stddef.h> | 7 #include <stddef.h> |
8 | 8 |
9 #include <memory> | 9 #include <memory> |
10 #include <string> | 10 #include <string> |
(...skipping 96 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
107 } | 107 } |
108 | 108 |
109 bool IsCapturingAudio() const { return audio_ref_count_ > 0; } | 109 bool IsCapturingAudio() const { return audio_ref_count_ > 0; } |
110 bool IsCapturingVideo() const { return video_ref_count_ > 0; } | 110 bool IsCapturingVideo() const { return video_ref_count_ > 0; } |
111 bool IsMirroring() const { return mirroring_ref_count_ > 0; } | 111 bool IsMirroring() const { return mirroring_ref_count_ > 0; } |
112 | 112 |
113 std::unique_ptr<content::MediaStreamUI> RegisterMediaStream( | 113 std::unique_ptr<content::MediaStreamUI> RegisterMediaStream( |
114 const content::MediaStreamDevices& devices); | 114 const content::MediaStreamDevices& devices); |
115 | 115 |
116 // Increment ref-counts up based on the type of each device provided. | 116 // Increment ref-counts up based on the type of each device provided. |
117 void AddDevices(const content::MediaStreamDevices& devices); | 117 void AddDevices(const content::MediaStreamDevices& devices, |
| 118 const base::Closure& close_callback); |
118 | 119 |
119 // Decrement ref-counts up based on the type of each device provided. | 120 // Decrement ref-counts up based on the type of each device provided. |
120 void RemoveDevices(const content::MediaStreamDevices& devices); | 121 void RemoveDevices(const content::MediaStreamDevices& devices); |
121 | 122 |
| 123 // Helper to call |stop_callback_|. |
| 124 void NotifyStopped(); |
| 125 |
122 private: | 126 private: |
123 // content::WebContentsObserver overrides. | 127 // content::WebContentsObserver overrides. |
124 void WebContentsDestroyed() override { | 128 void WebContentsDestroyed() override { |
125 indicator_->UnregisterWebContents(web_contents()); | 129 indicator_->UnregisterWebContents(web_contents()); |
126 } | 130 } |
127 | 131 |
128 scoped_refptr<MediaStreamCaptureIndicator> indicator_; | 132 scoped_refptr<MediaStreamCaptureIndicator> indicator_; |
129 int audio_ref_count_; | 133 int audio_ref_count_; |
130 int video_ref_count_; | 134 int video_ref_count_; |
131 int mirroring_ref_count_; | 135 int mirroring_ref_count_; |
132 | 136 |
| 137 base::Closure stop_callback_; |
133 base::WeakPtrFactory<WebContentsDeviceUsage> weak_factory_; | 138 base::WeakPtrFactory<WebContentsDeviceUsage> weak_factory_; |
134 | 139 |
135 DISALLOW_COPY_AND_ASSIGN(WebContentsDeviceUsage); | 140 DISALLOW_COPY_AND_ASSIGN(WebContentsDeviceUsage); |
136 }; | 141 }; |
137 | 142 |
138 // Implements MediaStreamUI interface. Instances of this class are created for | 143 // Implements MediaStreamUI interface. Instances of this class are created for |
139 // each MediaStream and their ownership is passed to MediaStream implementation | 144 // each MediaStream and their ownership is passed to MediaStream implementation |
140 // in the content layer. Each UIDelegate keeps a weak pointer to the | 145 // in the content layer. Each UIDelegate keeps a weak pointer to the |
141 // corresponding WebContentsDeviceUsage object to deliver updates about state of | 146 // corresponding WebContentsDeviceUsage object to deliver updates about state of |
142 // the stream. | 147 // the stream. |
(...skipping 11 matching lines...) Expand all Loading... |
154 if (started_ && device_usage_.get()) | 159 if (started_ && device_usage_.get()) |
155 device_usage_->RemoveDevices(devices_); | 160 device_usage_->RemoveDevices(devices_); |
156 } | 161 } |
157 | 162 |
158 private: | 163 private: |
159 // content::MediaStreamUI interface. | 164 // content::MediaStreamUI interface. |
160 gfx::NativeViewId OnStarted(const base::Closure& close_callback) override { | 165 gfx::NativeViewId OnStarted(const base::Closure& close_callback) override { |
161 DCHECK(!started_); | 166 DCHECK(!started_); |
162 started_ = true; | 167 started_ = true; |
163 if (device_usage_.get()) | 168 if (device_usage_.get()) |
164 device_usage_->AddDevices(devices_); | 169 device_usage_->AddDevices(devices_, close_callback); |
165 return 0; | 170 return 0; |
166 } | 171 } |
167 | 172 |
168 base::WeakPtr<WebContentsDeviceUsage> device_usage_; | 173 base::WeakPtr<WebContentsDeviceUsage> device_usage_; |
169 content::MediaStreamDevices devices_; | 174 content::MediaStreamDevices devices_; |
170 bool started_; | 175 bool started_; |
171 | 176 |
172 DISALLOW_COPY_AND_ASSIGN(UIDelegate); | 177 DISALLOW_COPY_AND_ASSIGN(UIDelegate); |
173 }; | 178 }; |
174 | 179 |
175 std::unique_ptr<content::MediaStreamUI> | 180 std::unique_ptr<content::MediaStreamUI> |
176 MediaStreamCaptureIndicator::WebContentsDeviceUsage::RegisterMediaStream( | 181 MediaStreamCaptureIndicator::WebContentsDeviceUsage::RegisterMediaStream( |
177 const content::MediaStreamDevices& devices) { | 182 const content::MediaStreamDevices& devices) { |
178 return base::WrapUnique(new UIDelegate(weak_factory_.GetWeakPtr(), devices)); | 183 return base::WrapUnique(new UIDelegate(weak_factory_.GetWeakPtr(), devices)); |
179 } | 184 } |
180 | 185 |
181 void MediaStreamCaptureIndicator::WebContentsDeviceUsage::AddDevices( | 186 void MediaStreamCaptureIndicator::WebContentsDeviceUsage::AddDevices( |
182 const content::MediaStreamDevices& devices) { | 187 const content::MediaStreamDevices& devices, |
| 188 const base::Closure& close_callback) { |
183 for (content::MediaStreamDevices::const_iterator it = devices.begin(); | 189 for (content::MediaStreamDevices::const_iterator it = devices.begin(); |
184 it != devices.end(); ++it) { | 190 it != devices.end(); ++it) { |
185 if (it->type == content::MEDIA_TAB_AUDIO_CAPTURE || | 191 if (content::IsScreenCaptureMediaType(it->type)) { |
186 it->type == content::MEDIA_TAB_VIDEO_CAPTURE) { | |
187 ++mirroring_ref_count_; | 192 ++mirroring_ref_count_; |
188 } else if (content::IsAudioInputMediaType(it->type)) { | 193 } else if (content::IsAudioInputMediaType(it->type)) { |
189 ++audio_ref_count_; | 194 ++audio_ref_count_; |
190 } else if (content::IsVideoMediaType(it->type)) { | 195 } else if (content::IsVideoMediaType(it->type)) { |
191 ++video_ref_count_; | 196 ++video_ref_count_; |
192 } else { | 197 } else { |
193 NOTIMPLEMENTED(); | 198 NOTIMPLEMENTED(); |
194 } | 199 } |
195 } | 200 } |
196 | 201 |
197 if (web_contents()) | 202 if (web_contents()) { |
| 203 stop_callback_ = close_callback; |
198 web_contents()->NotifyNavigationStateChanged(content::INVALIDATE_TYPE_TAB); | 204 web_contents()->NotifyNavigationStateChanged(content::INVALIDATE_TYPE_TAB); |
| 205 } |
199 | 206 |
200 indicator_->UpdateNotificationUserInterface(); | 207 indicator_->UpdateNotificationUserInterface(); |
201 } | 208 } |
202 | 209 |
203 void MediaStreamCaptureIndicator::WebContentsDeviceUsage::RemoveDevices( | 210 void MediaStreamCaptureIndicator::WebContentsDeviceUsage::RemoveDevices( |
204 const content::MediaStreamDevices& devices) { | 211 const content::MediaStreamDevices& devices) { |
205 for (content::MediaStreamDevices::const_iterator it = devices.begin(); | 212 for (content::MediaStreamDevices::const_iterator it = devices.begin(); |
206 it != devices.end(); ++it) { | 213 it != devices.end(); ++it) { |
207 if (it->type == content::MEDIA_TAB_AUDIO_CAPTURE || | 214 if (IsScreenCaptureMediaType(it->type)) { |
208 it->type == content::MEDIA_TAB_VIDEO_CAPTURE) { | |
209 --mirroring_ref_count_; | 215 --mirroring_ref_count_; |
210 } else if (content::IsAudioInputMediaType(it->type)) { | 216 } else if (content::IsAudioInputMediaType(it->type)) { |
211 --audio_ref_count_; | 217 --audio_ref_count_; |
212 } else if (content::IsVideoMediaType(it->type)) { | 218 } else if (content::IsVideoMediaType(it->type)) { |
213 --video_ref_count_; | 219 --video_ref_count_; |
214 } else { | 220 } else { |
215 NOTIMPLEMENTED(); | 221 NOTIMPLEMENTED(); |
216 } | 222 } |
217 } | 223 } |
218 | 224 |
219 DCHECK_GE(audio_ref_count_, 0); | 225 DCHECK_GE(audio_ref_count_, 0); |
220 DCHECK_GE(video_ref_count_, 0); | 226 DCHECK_GE(video_ref_count_, 0); |
221 DCHECK_GE(mirroring_ref_count_, 0); | 227 DCHECK_GE(mirroring_ref_count_, 0); |
222 | 228 |
223 web_contents()->NotifyNavigationStateChanged(content::INVALIDATE_TYPE_TAB); | 229 web_contents()->NotifyNavigationStateChanged(content::INVALIDATE_TYPE_TAB); |
224 indicator_->UpdateNotificationUserInterface(); | 230 indicator_->UpdateNotificationUserInterface(); |
225 } | 231 } |
226 | 232 |
| 233 void MediaStreamCaptureIndicator::WebContentsDeviceUsage::NotifyStopped() { |
| 234 if (!stop_callback_.is_null()) { |
| 235 base::Closure callback = stop_callback_; |
| 236 stop_callback_.Reset(); |
| 237 callback.Run(); |
| 238 } |
| 239 } |
| 240 |
227 MediaStreamCaptureIndicator::MediaStreamCaptureIndicator() | 241 MediaStreamCaptureIndicator::MediaStreamCaptureIndicator() |
228 : status_icon_(NULL), | 242 : status_icon_(NULL), |
229 mic_image_(NULL), | 243 mic_image_(NULL), |
230 camera_image_(NULL) { | 244 camera_image_(NULL) { |
231 } | 245 } |
232 | 246 |
233 MediaStreamCaptureIndicator::~MediaStreamCaptureIndicator() { | 247 MediaStreamCaptureIndicator::~MediaStreamCaptureIndicator() { |
234 // The user is responsible for cleaning up by reporting the closure of any | 248 // The user is responsible for cleaning up by reporting the closure of any |
235 // opened devices. However, there exists a race condition at shutdown: The UI | 249 // opened devices. However, there exists a race condition at shutdown: The UI |
236 // thread may be stopped before CaptureDevicesClosed() posts the task to | 250 // thread may be stopped before CaptureDevicesClosed() posts the task to |
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
290 } | 304 } |
291 | 305 |
292 bool MediaStreamCaptureIndicator::IsBeingMirrored( | 306 bool MediaStreamCaptureIndicator::IsBeingMirrored( |
293 content::WebContents* web_contents) const { | 307 content::WebContents* web_contents) const { |
294 DCHECK_CURRENTLY_ON(BrowserThread::UI); | 308 DCHECK_CURRENTLY_ON(BrowserThread::UI); |
295 | 309 |
296 WebContentsDeviceUsage* usage = usage_map_.get(web_contents); | 310 WebContentsDeviceUsage* usage = usage_map_.get(web_contents); |
297 return usage && usage->IsMirroring(); | 311 return usage && usage->IsMirroring(); |
298 } | 312 } |
299 | 313 |
| 314 void MediaStreamCaptureIndicator::NotifyStopped( |
| 315 content::WebContents* web_contents) const { |
| 316 DCHECK_CURRENTLY_ON(BrowserThread::UI); |
| 317 |
| 318 WebContentsDeviceUsage* usage = usage_map_.get(web_contents); |
| 319 if (usage) |
| 320 usage->NotifyStopped(); |
| 321 } |
| 322 |
300 void MediaStreamCaptureIndicator::UnregisterWebContents( | 323 void MediaStreamCaptureIndicator::UnregisterWebContents( |
301 WebContents* web_contents) { | 324 WebContents* web_contents) { |
302 usage_map_.erase(web_contents); | 325 usage_map_.erase(web_contents); |
303 UpdateNotificationUserInterface(); | 326 UpdateNotificationUserInterface(); |
304 } | 327 } |
305 | 328 |
306 void MediaStreamCaptureIndicator::MaybeCreateStatusTrayIcon(bool audio, | 329 void MediaStreamCaptureIndicator::MaybeCreateStatusTrayIcon(bool audio, |
307 bool video) { | 330 bool video) { |
308 DCHECK_CURRENTLY_ON(BrowserThread::UI); | 331 DCHECK_CURRENTLY_ON(BrowserThread::UI); |
309 | 332 |
(...skipping 122 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
432 } else if (audio && !video) { | 455 } else if (audio && !video) { |
433 message_id = IDS_MEDIA_STREAM_STATUS_TRAY_TEXT_AUDIO_ONLY; | 456 message_id = IDS_MEDIA_STREAM_STATUS_TRAY_TEXT_AUDIO_ONLY; |
434 *image = *mic_image_; | 457 *image = *mic_image_; |
435 } else if (!audio && video) { | 458 } else if (!audio && video) { |
436 message_id = IDS_MEDIA_STREAM_STATUS_TRAY_TEXT_VIDEO_ONLY; | 459 message_id = IDS_MEDIA_STREAM_STATUS_TRAY_TEXT_VIDEO_ONLY; |
437 *image = *camera_image_; | 460 *image = *camera_image_; |
438 } | 461 } |
439 | 462 |
440 *tool_tip = l10n_util::GetStringUTF16(message_id); | 463 *tool_tip = l10n_util::GetStringUTF16(message_id); |
441 } | 464 } |
OLD | NEW |