| 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/webrtc/media_stream_capture_indicator.h" | 5 #include "chrome/browser/media/webrtc/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::MakeUnique<UIDelegate>(weak_factory_.GetWeakPtr(), devices); | 183 return base::MakeUnique<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 DCHECK(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 |