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 } |
| 131 bool IsMirroringType(content::MediaStreamType type); |
127 | 132 |
128 scoped_refptr<MediaStreamCaptureIndicator> indicator_; | 133 scoped_refptr<MediaStreamCaptureIndicator> indicator_; |
129 int audio_ref_count_; | 134 int audio_ref_count_; |
130 int video_ref_count_; | 135 int video_ref_count_; |
131 int mirroring_ref_count_; | 136 int mirroring_ref_count_; |
132 | 137 |
| 138 base::Closure stop_callback_; |
133 base::WeakPtrFactory<WebContentsDeviceUsage> weak_factory_; | 139 base::WeakPtrFactory<WebContentsDeviceUsage> weak_factory_; |
134 | 140 |
135 DISALLOW_COPY_AND_ASSIGN(WebContentsDeviceUsage); | 141 DISALLOW_COPY_AND_ASSIGN(WebContentsDeviceUsage); |
136 }; | 142 }; |
137 | 143 |
138 // Implements MediaStreamUI interface. Instances of this class are created for | 144 // Implements MediaStreamUI interface. Instances of this class are created for |
139 // each MediaStream and their ownership is passed to MediaStream implementation | 145 // each MediaStream and their ownership is passed to MediaStream implementation |
140 // in the content layer. Each UIDelegate keeps a weak pointer to the | 146 // in the content layer. Each UIDelegate keeps a weak pointer to the |
141 // corresponding WebContentsDeviceUsage object to deliver updates about state of | 147 // corresponding WebContentsDeviceUsage object to deliver updates about state of |
142 // the stream. | 148 // the stream. |
(...skipping 11 matching lines...) Expand all Loading... |
154 if (started_ && device_usage_.get()) | 160 if (started_ && device_usage_.get()) |
155 device_usage_->RemoveDevices(devices_); | 161 device_usage_->RemoveDevices(devices_); |
156 } | 162 } |
157 | 163 |
158 private: | 164 private: |
159 // content::MediaStreamUI interface. | 165 // content::MediaStreamUI interface. |
160 gfx::NativeViewId OnStarted(const base::Closure& close_callback) override { | 166 gfx::NativeViewId OnStarted(const base::Closure& close_callback) override { |
161 DCHECK(!started_); | 167 DCHECK(!started_); |
162 started_ = true; | 168 started_ = true; |
163 if (device_usage_.get()) | 169 if (device_usage_.get()) |
164 device_usage_->AddDevices(devices_); | 170 device_usage_->AddDevices(devices_, close_callback); |
165 return 0; | 171 return 0; |
166 } | 172 } |
167 | 173 |
168 base::WeakPtr<WebContentsDeviceUsage> device_usage_; | 174 base::WeakPtr<WebContentsDeviceUsage> device_usage_; |
169 content::MediaStreamDevices devices_; | 175 content::MediaStreamDevices devices_; |
170 bool started_; | 176 bool started_; |
171 | 177 |
172 DISALLOW_COPY_AND_ASSIGN(UIDelegate); | 178 DISALLOW_COPY_AND_ASSIGN(UIDelegate); |
173 }; | 179 }; |
174 | 180 |
175 std::unique_ptr<content::MediaStreamUI> | 181 std::unique_ptr<content::MediaStreamUI> |
176 MediaStreamCaptureIndicator::WebContentsDeviceUsage::RegisterMediaStream( | 182 MediaStreamCaptureIndicator::WebContentsDeviceUsage::RegisterMediaStream( |
177 const content::MediaStreamDevices& devices) { | 183 const content::MediaStreamDevices& devices) { |
178 return base::WrapUnique(new UIDelegate(weak_factory_.GetWeakPtr(), devices)); | 184 return base::WrapUnique(new UIDelegate(weak_factory_.GetWeakPtr(), devices)); |
179 } | 185 } |
180 | 186 |
181 void MediaStreamCaptureIndicator::WebContentsDeviceUsage::AddDevices( | 187 void MediaStreamCaptureIndicator::WebContentsDeviceUsage::AddDevices( |
182 const content::MediaStreamDevices& devices) { | 188 const content::MediaStreamDevices& devices, |
| 189 const base::Closure& close_callback) { |
183 for (content::MediaStreamDevices::const_iterator it = devices.begin(); | 190 for (content::MediaStreamDevices::const_iterator it = devices.begin(); |
184 it != devices.end(); ++it) { | 191 it != devices.end(); ++it) { |
185 if (it->type == content::MEDIA_TAB_AUDIO_CAPTURE || | 192 if (IsMirroringType(it->type)) { |
186 it->type == content::MEDIA_TAB_VIDEO_CAPTURE) { | |
187 ++mirroring_ref_count_; | 193 ++mirroring_ref_count_; |
188 } else if (content::IsAudioInputMediaType(it->type)) { | 194 } else if (content::IsAudioInputMediaType(it->type)) { |
189 ++audio_ref_count_; | 195 ++audio_ref_count_; |
190 } else if (content::IsVideoMediaType(it->type)) { | 196 } else if (content::IsVideoMediaType(it->type)) { |
191 ++video_ref_count_; | 197 ++video_ref_count_; |
192 } else { | 198 } else { |
193 NOTIMPLEMENTED(); | 199 NOTIMPLEMENTED(); |
194 } | 200 } |
195 } | 201 } |
196 | 202 |
197 if (web_contents()) | 203 if (web_contents()) { |
| 204 stop_callback_ = close_callback; |
198 web_contents()->NotifyNavigationStateChanged(content::INVALIDATE_TYPE_TAB); | 205 web_contents()->NotifyNavigationStateChanged(content::INVALIDATE_TYPE_TAB); |
| 206 } |
199 | 207 |
200 indicator_->UpdateNotificationUserInterface(); | 208 indicator_->UpdateNotificationUserInterface(); |
201 } | 209 } |
202 | 210 |
203 void MediaStreamCaptureIndicator::WebContentsDeviceUsage::RemoveDevices( | 211 void MediaStreamCaptureIndicator::WebContentsDeviceUsage::RemoveDevices( |
204 const content::MediaStreamDevices& devices) { | 212 const content::MediaStreamDevices& devices) { |
205 for (content::MediaStreamDevices::const_iterator it = devices.begin(); | 213 for (content::MediaStreamDevices::const_iterator it = devices.begin(); |
206 it != devices.end(); ++it) { | 214 it != devices.end(); ++it) { |
207 if (it->type == content::MEDIA_TAB_AUDIO_CAPTURE || | 215 if (IsMirroringType(it->type)) { |
208 it->type == content::MEDIA_TAB_VIDEO_CAPTURE) { | |
209 --mirroring_ref_count_; | 216 --mirroring_ref_count_; |
210 } else if (content::IsAudioInputMediaType(it->type)) { | 217 } else if (content::IsAudioInputMediaType(it->type)) { |
211 --audio_ref_count_; | 218 --audio_ref_count_; |
212 } else if (content::IsVideoMediaType(it->type)) { | 219 } else if (content::IsVideoMediaType(it->type)) { |
213 --video_ref_count_; | 220 --video_ref_count_; |
214 } else { | 221 } else { |
215 NOTIMPLEMENTED(); | 222 NOTIMPLEMENTED(); |
216 } | 223 } |
217 } | 224 } |
218 | 225 |
219 DCHECK_GE(audio_ref_count_, 0); | 226 DCHECK_GE(audio_ref_count_, 0); |
220 DCHECK_GE(video_ref_count_, 0); | 227 DCHECK_GE(video_ref_count_, 0); |
221 DCHECK_GE(mirroring_ref_count_, 0); | 228 DCHECK_GE(mirroring_ref_count_, 0); |
222 | 229 |
223 web_contents()->NotifyNavigationStateChanged(content::INVALIDATE_TYPE_TAB); | 230 web_contents()->NotifyNavigationStateChanged(content::INVALIDATE_TYPE_TAB); |
224 indicator_->UpdateNotificationUserInterface(); | 231 indicator_->UpdateNotificationUserInterface(); |
225 } | 232 } |
226 | 233 |
| 234 void MediaStreamCaptureIndicator::WebContentsDeviceUsage::NotifyStopped() { |
| 235 if (!stop_callback_.is_null()) { |
| 236 base::Closure callback = stop_callback_; |
| 237 stop_callback_.Reset(); |
| 238 callback.Run(); |
| 239 } |
| 240 } |
| 241 |
| 242 bool MediaStreamCaptureIndicator::WebContentsDeviceUsage::IsMirroringType( |
| 243 content::MediaStreamType type) { |
| 244 #if defined(OS_ANDROID) |
| 245 return type == content::MEDIA_TAB_AUDIO_CAPTURE || |
| 246 type == content::MEDIA_TAB_VIDEO_CAPTURE || |
| 247 type == content::MEDIA_DESKTOP_VIDEO_CAPTURE; |
| 248 #else |
| 249 return type == content::MEDIA_TAB_AUDIO_CAPTURE || |
| 250 type == content::MEDIA_TAB_VIDEO_CAPTURE; |
| 251 #endif |
| 252 } |
| 253 |
227 MediaStreamCaptureIndicator::MediaStreamCaptureIndicator() | 254 MediaStreamCaptureIndicator::MediaStreamCaptureIndicator() |
228 : status_icon_(NULL), | 255 : status_icon_(NULL), |
229 mic_image_(NULL), | 256 mic_image_(NULL), |
230 camera_image_(NULL) { | 257 camera_image_(NULL) { |
231 } | 258 } |
232 | 259 |
233 MediaStreamCaptureIndicator::~MediaStreamCaptureIndicator() { | 260 MediaStreamCaptureIndicator::~MediaStreamCaptureIndicator() { |
234 // The user is responsible for cleaning up by reporting the closure of any | 261 // 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 | 262 // opened devices. However, there exists a race condition at shutdown: The UI |
236 // thread may be stopped before CaptureDevicesClosed() posts the task to | 263 // thread may be stopped before CaptureDevicesClosed() posts the task to |
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
290 } | 317 } |
291 | 318 |
292 bool MediaStreamCaptureIndicator::IsBeingMirrored( | 319 bool MediaStreamCaptureIndicator::IsBeingMirrored( |
293 content::WebContents* web_contents) const { | 320 content::WebContents* web_contents) const { |
294 DCHECK_CURRENTLY_ON(BrowserThread::UI); | 321 DCHECK_CURRENTLY_ON(BrowserThread::UI); |
295 | 322 |
296 WebContentsDeviceUsage* usage = usage_map_.get(web_contents); | 323 WebContentsDeviceUsage* usage = usage_map_.get(web_contents); |
297 return usage && usage->IsMirroring(); | 324 return usage && usage->IsMirroring(); |
298 } | 325 } |
299 | 326 |
| 327 void MediaStreamCaptureIndicator::NotifyStopped( |
| 328 content::WebContents* web_contents) const { |
| 329 DCHECK_CURRENTLY_ON(BrowserThread::UI); |
| 330 |
| 331 WebContentsDeviceUsage* usage = usage_map_.get(web_contents); |
| 332 if (usage) |
| 333 usage->NotifyStopped(); |
| 334 } |
| 335 |
300 void MediaStreamCaptureIndicator::UnregisterWebContents( | 336 void MediaStreamCaptureIndicator::UnregisterWebContents( |
301 WebContents* web_contents) { | 337 WebContents* web_contents) { |
302 usage_map_.erase(web_contents); | 338 usage_map_.erase(web_contents); |
303 UpdateNotificationUserInterface(); | 339 UpdateNotificationUserInterface(); |
304 } | 340 } |
305 | 341 |
306 void MediaStreamCaptureIndicator::MaybeCreateStatusTrayIcon(bool audio, | 342 void MediaStreamCaptureIndicator::MaybeCreateStatusTrayIcon(bool audio, |
307 bool video) { | 343 bool video) { |
308 DCHECK_CURRENTLY_ON(BrowserThread::UI); | 344 DCHECK_CURRENTLY_ON(BrowserThread::UI); |
309 | 345 |
(...skipping 122 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
432 } else if (audio && !video) { | 468 } else if (audio && !video) { |
433 message_id = IDS_MEDIA_STREAM_STATUS_TRAY_TEXT_AUDIO_ONLY; | 469 message_id = IDS_MEDIA_STREAM_STATUS_TRAY_TEXT_AUDIO_ONLY; |
434 *image = *mic_image_; | 470 *image = *mic_image_; |
435 } else if (!audio && video) { | 471 } else if (!audio && video) { |
436 message_id = IDS_MEDIA_STREAM_STATUS_TRAY_TEXT_VIDEO_ONLY; | 472 message_id = IDS_MEDIA_STREAM_STATUS_TRAY_TEXT_VIDEO_ONLY; |
437 *image = *camera_image_; | 473 *image = *camera_image_; |
438 } | 474 } |
439 | 475 |
440 *tool_tip = l10n_util::GetStringUTF16(message_id); | 476 *tool_tip = l10n_util::GetStringUTF16(message_id); |
441 } | 477 } |
OLD | NEW |