| 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 "content/browser/renderer_host/media/media_stream_manager.h" | 5 #include "content/browser/renderer_host/media/media_stream_manager.h" | 
| 6 | 6 | 
| 7 #include <stddef.h> | 7 #include <stddef.h> | 
| 8 #include <stdint.h> | 8 #include <stdint.h> | 
| 9 #include <string.h> | 9 #include <string.h> | 
| 10 #include <algorithm> | 10 #include <algorithm> | 
| (...skipping 159 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 170                                 const StreamDeviceInfoArray& device_infos) { | 170                                 const StreamDeviceInfoArray& device_infos) { | 
| 171   std::string output_string = | 171   std::string output_string = | 
| 172       base::StringPrintf("Getting devices for stream type %d:\n", stream_type); | 172       base::StringPrintf("Getting devices for stream type %d:\n", stream_type); | 
| 173   if (device_infos.empty()) | 173   if (device_infos.empty()) | 
| 174     return output_string + "No devices found."; | 174     return output_string + "No devices found."; | 
| 175   for (const content::StreamDeviceInfo& device_info : device_infos) | 175   for (const content::StreamDeviceInfo& device_info : device_infos) | 
| 176     output_string += "  " + device_info.device.name + "\n"; | 176     output_string += "  " + device_info.device.name + "\n"; | 
| 177   return output_string; | 177   return output_string; | 
| 178 } | 178 } | 
| 179 | 179 | 
|  | 180 // Needed for MediaStreamManager::GenerateStream below. | 
|  | 181 std::string ReturnEmptySalt() { | 
|  | 182   return std::string(); | 
|  | 183 } | 
|  | 184 | 
| 180 // Clears the MediaStreamDevice.name from all devices in |devices|. | 185 // Clears the MediaStreamDevice.name from all devices in |devices|. | 
| 181 void ClearDeviceLabels(content::StreamDeviceInfoArray* devices) { | 186 void ClearDeviceLabels(content::StreamDeviceInfoArray* devices) { | 
| 182   for (content::StreamDeviceInfo& device_info : *devices) | 187   for (content::StreamDeviceInfo& device_info : *devices) | 
| 183     device_info.device.name.clear(); | 188     device_info.device.name.clear(); | 
| 184 } | 189 } | 
| 185 | 190 | 
| 186 bool CalledOnIOThread() { | 191 bool CalledOnIOThread() { | 
| 187   // Check if this function call is on the IO thread, except for unittests where | 192   // Check if this function call is on the IO thread, except for unittests where | 
| 188   // an IO thread might not have been created. | 193   // an IO thread might not have been created. | 
| 189   return BrowserThread::CurrentlyOn(BrowserThread::IO) || | 194   return BrowserThread::CurrentlyOn(BrowserThread::IO) || | 
| (...skipping 16 matching lines...) Expand all  Loading... | 
| 206 class MediaStreamManager::DeviceRequest { | 211 class MediaStreamManager::DeviceRequest { | 
| 207  public: | 212  public: | 
| 208   DeviceRequest(MediaStreamRequester* requester, | 213   DeviceRequest(MediaStreamRequester* requester, | 
| 209                 int requesting_process_id, | 214                 int requesting_process_id, | 
| 210                 int requesting_frame_id, | 215                 int requesting_frame_id, | 
| 211                 int page_request_id, | 216                 int page_request_id, | 
| 212                 const url::Origin& security_origin, | 217                 const url::Origin& security_origin, | 
| 213                 bool user_gesture, | 218                 bool user_gesture, | 
| 214                 MediaStreamRequestType request_type, | 219                 MediaStreamRequestType request_type, | 
| 215                 const StreamControls& controls, | 220                 const StreamControls& controls, | 
| 216                 const std::string& salt) | 221                 const ResourceContext::SaltCallback& salt_callback) | 
| 217       : requester(requester), | 222       : requester(requester), | 
| 218         requesting_process_id(requesting_process_id), | 223         requesting_process_id(requesting_process_id), | 
| 219         requesting_frame_id(requesting_frame_id), | 224         requesting_frame_id(requesting_frame_id), | 
| 220         page_request_id(page_request_id), | 225         page_request_id(page_request_id), | 
| 221         security_origin(security_origin), | 226         security_origin(security_origin), | 
| 222         user_gesture(user_gesture), | 227         user_gesture(user_gesture), | 
| 223         request_type(request_type), | 228         request_type(request_type), | 
| 224         controls(controls), | 229         controls(controls), | 
| 225         salt(salt), | 230         salt_callback(salt_callback), | 
| 226         state_(NUM_MEDIA_TYPES, MEDIA_REQUEST_STATE_NOT_REQUESTED), | 231         state_(NUM_MEDIA_TYPES, MEDIA_REQUEST_STATE_NOT_REQUESTED), | 
| 227         audio_type_(MEDIA_NO_SERVICE), | 232         audio_type_(MEDIA_NO_SERVICE), | 
| 228         video_type_(MEDIA_NO_SERVICE), | 233         video_type_(MEDIA_NO_SERVICE), | 
| 229         target_process_id_(-1), | 234         target_process_id_(-1), | 
| 230         target_frame_id_(-1) {} | 235         target_frame_id_(-1) {} | 
| 231 | 236 | 
| 232   ~DeviceRequest() {} | 237   ~DeviceRequest() {} | 
| 233 | 238 | 
| 234   void SetAudioType(MediaStreamType audio_type) { | 239   void SetAudioType(MediaStreamType audio_type) { | 
| 235     DCHECK(IsAudioInputMediaType(audio_type) || | 240     DCHECK(IsAudioInputMediaType(audio_type) || | 
| (...skipping 98 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 334   const int page_request_id; | 339   const int page_request_id; | 
| 335 | 340 | 
| 336   const url::Origin security_origin; | 341   const url::Origin security_origin; | 
| 337 | 342 | 
| 338   const bool user_gesture; | 343   const bool user_gesture; | 
| 339 | 344 | 
| 340   const MediaStreamRequestType request_type; | 345   const MediaStreamRequestType request_type; | 
| 341 | 346 | 
| 342   const StreamControls controls; | 347   const StreamControls controls; | 
| 343 | 348 | 
| 344   const std::string salt; | 349   ResourceContext::SaltCallback salt_callback; | 
| 345 | 350 | 
| 346   StreamDeviceInfoArray devices; | 351   StreamDeviceInfoArray devices; | 
| 347 | 352 | 
| 348   // Callback to the requester which audio/video devices have been selected. | 353   // Callback to the requester which audio/video devices have been selected. | 
| 349   // It can be null if the requester has no interest to know the result. | 354   // It can be null if the requester has no interest to know the result. | 
| 350   // Currently it is only used by |DEVICE_ACCESS| type. | 355   // Currently it is only used by |DEVICE_ACCESS| type. | 
| 351   MediaStreamManager::MediaRequestResponseCallback callback; | 356   MediaStreamManager::MediaRequestResponseCallback callback; | 
| 352 | 357 | 
| 353   std::unique_ptr<MediaStreamUIProxy> ui_proxy; | 358   std::unique_ptr<MediaStreamUIProxy> ui_proxy; | 
| 354 | 359 | 
| (...skipping 99 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 454     int render_process_id, | 459     int render_process_id, | 
| 455     int render_frame_id, | 460     int render_frame_id, | 
| 456     int page_request_id, | 461     int page_request_id, | 
| 457     const StreamControls& controls, | 462     const StreamControls& controls, | 
| 458     const url::Origin& security_origin, | 463     const url::Origin& security_origin, | 
| 459     const MediaRequestResponseCallback& callback) { | 464     const MediaRequestResponseCallback& callback) { | 
| 460   DCHECK_CURRENTLY_ON(BrowserThread::IO); | 465   DCHECK_CURRENTLY_ON(BrowserThread::IO); | 
| 461 | 466 | 
| 462   // TODO(perkj): The argument list with NULL parameters to DeviceRequest | 467   // TODO(perkj): The argument list with NULL parameters to DeviceRequest | 
| 463   // suggests that this is the wrong design. Can this be refactored? | 468   // suggests that this is the wrong design. Can this be refactored? | 
| 464   DeviceRequest* request = | 469   DeviceRequest* request = new DeviceRequest( | 
| 465       new DeviceRequest(NULL, render_process_id, render_frame_id, | 470       NULL, render_process_id, render_frame_id, page_request_id, | 
| 466                         page_request_id, security_origin, | 471       security_origin, | 
| 467                         false,  // user gesture | 472       false,  // user gesture | 
| 468                         MEDIA_DEVICE_ACCESS, controls, std::string()); | 473       MEDIA_DEVICE_ACCESS, controls, base::Bind(&ReturnEmptySalt)); | 
| 469 | 474 | 
| 470   const std::string& label = AddRequest(request); | 475   const std::string& label = AddRequest(request); | 
| 471 | 476 | 
| 472   request->callback = callback; | 477   request->callback = callback; | 
| 473   // Post a task and handle the request asynchronously. The reason is that the | 478   // Post a task and handle the request asynchronously. The reason is that the | 
| 474   // requester won't have a label for the request until this function returns | 479   // requester won't have a label for the request until this function returns | 
| 475   // and thus can not handle a response. Using base::Unretained is safe since | 480   // and thus can not handle a response. Using base::Unretained is safe since | 
| 476   // MediaStreamManager is deleted on the UI thread, after the IO thread has | 481   // MediaStreamManager is deleted on the UI thread, after the IO thread has | 
| 477   // been stopped. | 482   // been stopped. | 
| 478   BrowserThread::PostTask( | 483   BrowserThread::PostTask( | 
| 479       BrowserThread::IO, FROM_HERE, | 484       BrowserThread::IO, FROM_HERE, | 
| 480       base::Bind(&MediaStreamManager::SetupRequest, | 485       base::Bind(&MediaStreamManager::SetupRequest, | 
| 481                  base::Unretained(this), label)); | 486                  base::Unretained(this), label)); | 
| 482   return label; | 487   return label; | 
| 483 } | 488 } | 
| 484 | 489 | 
| 485 void MediaStreamManager::GenerateStream(MediaStreamRequester* requester, | 490 void MediaStreamManager::GenerateStream(MediaStreamRequester* requester, | 
| 486                                         int render_process_id, | 491                                         int render_process_id, | 
| 487                                         int render_frame_id, | 492                                         int render_frame_id, | 
| 488                                         const std::string& salt, | 493                                         const ResourceContext::SaltCallback& sc, | 
| 489                                         int page_request_id, | 494                                         int page_request_id, | 
| 490                                         const StreamControls& controls, | 495                                         const StreamControls& controls, | 
| 491                                         const url::Origin& security_origin, | 496                                         const url::Origin& security_origin, | 
| 492                                         bool user_gesture) { | 497                                         bool user_gesture) { | 
| 493   DCHECK_CURRENTLY_ON(BrowserThread::IO); | 498   DCHECK_CURRENTLY_ON(BrowserThread::IO); | 
| 494   DVLOG(1) << "GenerateStream()"; | 499   DVLOG(1) << "GenerateStream()"; | 
| 495 | 500 | 
| 496   DeviceRequest* request = new DeviceRequest( | 501   DeviceRequest* request = new DeviceRequest( | 
| 497       requester, render_process_id, render_frame_id, page_request_id, | 502       requester, render_process_id, render_frame_id, page_request_id, | 
| 498       security_origin, user_gesture, MEDIA_GENERATE_STREAM, controls, salt); | 503       security_origin, user_gesture, MEDIA_GENERATE_STREAM, controls, sc); | 
| 499 | 504 | 
| 500   const std::string& label = AddRequest(request); | 505   const std::string& label = AddRequest(request); | 
| 501 | 506 | 
| 502   // Post a task and handle the request asynchronously. The reason is that the | 507   // Post a task and handle the request asynchronously. The reason is that the | 
| 503   // requester won't have a label for the request until this function returns | 508   // requester won't have a label for the request until this function returns | 
| 504   // and thus can not handle a response. Using base::Unretained is safe since | 509   // and thus can not handle a response. Using base::Unretained is safe since | 
| 505   // MediaStreamManager is deleted on the UI thread, after the IO thread has | 510   // MediaStreamManager is deleted on the UI thread, after the IO thread has | 
| 506   // been stopped. | 511   // been stopped. | 
| 507   BrowserThread::PostTask( | 512   BrowserThread::PostTask( | 
| 508       BrowserThread::IO, FROM_HERE, | 513       BrowserThread::IO, FROM_HERE, | 
| (...skipping 164 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 673         request->SetState(type, MEDIA_REQUEST_STATE_CLOSING); | 678         request->SetState(type, MEDIA_REQUEST_STATE_CLOSING); | 
| 674       } | 679       } | 
| 675     } | 680     } | 
| 676   } | 681   } | 
| 677 } | 682 } | 
| 678 | 683 | 
| 679 std::string MediaStreamManager::EnumerateDevices( | 684 std::string MediaStreamManager::EnumerateDevices( | 
| 680     MediaStreamRequester* requester, | 685     MediaStreamRequester* requester, | 
| 681     int render_process_id, | 686     int render_process_id, | 
| 682     int render_frame_id, | 687     int render_frame_id, | 
| 683     const std::string& salt, | 688     const ResourceContext::SaltCallback& sc, | 
| 684     int page_request_id, | 689     int page_request_id, | 
| 685     MediaStreamType type, | 690     MediaStreamType type, | 
| 686     const url::Origin& security_origin) { | 691     const url::Origin& security_origin) { | 
| 687   DCHECK_CURRENTLY_ON(BrowserThread::IO); | 692   DCHECK_CURRENTLY_ON(BrowserThread::IO); | 
| 688   DCHECK(requester); | 693   DCHECK(requester); | 
| 689   DCHECK(type == MEDIA_DEVICE_AUDIO_CAPTURE || | 694   DCHECK(type == MEDIA_DEVICE_AUDIO_CAPTURE || | 
| 690          type == MEDIA_DEVICE_VIDEO_CAPTURE || | 695          type == MEDIA_DEVICE_VIDEO_CAPTURE || | 
| 691          type == MEDIA_DEVICE_AUDIO_OUTPUT); | 696          type == MEDIA_DEVICE_AUDIO_OUTPUT); | 
| 692 | 697 | 
| 693   DeviceRequest* request = | 698   DeviceRequest* request = | 
| 694       new DeviceRequest(requester, render_process_id, render_frame_id, | 699       new DeviceRequest(requester, render_process_id, render_frame_id, | 
| 695                         page_request_id, security_origin, | 700                         page_request_id, security_origin, | 
| 696                         false,  // user gesture | 701                         false,  // user gesture | 
| 697                         MEDIA_ENUMERATE_DEVICES, StreamControls(), salt); | 702                         MEDIA_ENUMERATE_DEVICES, StreamControls(), sc); | 
| 698   if (IsAudioInputMediaType(type) || type == MEDIA_DEVICE_AUDIO_OUTPUT) | 703   if (IsAudioInputMediaType(type) || type == MEDIA_DEVICE_AUDIO_OUTPUT) | 
| 699     request->SetAudioType(type); | 704     request->SetAudioType(type); | 
| 700   else if (IsVideoMediaType(type)) | 705   else if (IsVideoMediaType(type)) | 
| 701     request->SetVideoType(type); | 706     request->SetVideoType(type); | 
| 702 | 707 | 
| 703   const std::string& label = AddRequest(request); | 708   const std::string& label = AddRequest(request); | 
| 704   // Post a task and handle the request asynchronously. The reason is that the | 709   // Post a task and handle the request asynchronously. The reason is that the | 
| 705   // requester won't have a label for the request until this function returns | 710   // requester won't have a label for the request until this function returns | 
| 706   // and thus can not handle a response. Using base::Unretained is safe since | 711   // and thus can not handle a response. Using base::Unretained is safe since | 
| 707   // MediaStreamManager is deleted on the UI thread, after the IO thread has | 712   // MediaStreamManager is deleted on the UI thread, after the IO thread has | 
| (...skipping 81 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 789     } | 794     } | 
| 790   } | 795   } | 
| 791 | 796 | 
| 792   --active_enumeration_ref_count_[MEDIA_DEVICE_AUDIO_OUTPUT]; | 797   --active_enumeration_ref_count_[MEDIA_DEVICE_AUDIO_OUTPUT]; | 
| 793   DCHECK_GE(active_enumeration_ref_count_[MEDIA_DEVICE_AUDIO_OUTPUT], 0); | 798   DCHECK_GE(active_enumeration_ref_count_[MEDIA_DEVICE_AUDIO_OUTPUT], 0); | 
| 794 } | 799 } | 
| 795 | 800 | 
| 796 void MediaStreamManager::OpenDevice(MediaStreamRequester* requester, | 801 void MediaStreamManager::OpenDevice(MediaStreamRequester* requester, | 
| 797                                     int render_process_id, | 802                                     int render_process_id, | 
| 798                                     int render_frame_id, | 803                                     int render_frame_id, | 
| 799                                     const std::string& salt, | 804                                     const ResourceContext::SaltCallback& sc, | 
| 800                                     int page_request_id, | 805                                     int page_request_id, | 
| 801                                     const std::string& device_id, | 806                                     const std::string& device_id, | 
| 802                                     MediaStreamType type, | 807                                     MediaStreamType type, | 
| 803                                     const url::Origin& security_origin) { | 808                                     const url::Origin& security_origin) { | 
| 804   DCHECK_CURRENTLY_ON(BrowserThread::IO); | 809   DCHECK_CURRENTLY_ON(BrowserThread::IO); | 
| 805   DCHECK(type == MEDIA_DEVICE_AUDIO_CAPTURE || | 810   DCHECK(type == MEDIA_DEVICE_AUDIO_CAPTURE || | 
| 806          type == MEDIA_DEVICE_VIDEO_CAPTURE); | 811          type == MEDIA_DEVICE_VIDEO_CAPTURE); | 
| 807   DVLOG(1) << "OpenDevice ({page_request_id = " << page_request_id <<  "})"; | 812   DVLOG(1) << "OpenDevice ({page_request_id = " << page_request_id <<  "})"; | 
| 808   StreamControls controls; | 813   StreamControls controls; | 
| 809   if (IsAudioInputMediaType(type)) { | 814   if (IsAudioInputMediaType(type)) { | 
| 810     controls.audio.requested = true; | 815     controls.audio.requested = true; | 
| 811     controls.audio.device_ids.push_back(device_id); | 816     controls.audio.device_ids.push_back(device_id); | 
| 812   } else if (IsVideoMediaType(type)) { | 817   } else if (IsVideoMediaType(type)) { | 
| 813     controls.video.requested = true; | 818     controls.video.requested = true; | 
| 814     controls.video.device_ids.push_back(device_id); | 819     controls.video.device_ids.push_back(device_id); | 
| 815   } else { | 820   } else { | 
| 816     NOTREACHED(); | 821     NOTREACHED(); | 
| 817   } | 822   } | 
| 818   DeviceRequest* request = | 823   DeviceRequest* request = | 
| 819       new DeviceRequest(requester, render_process_id, render_frame_id, | 824       new DeviceRequest(requester, render_process_id, render_frame_id, | 
| 820                         page_request_id, security_origin, | 825                         page_request_id, security_origin, | 
| 821                         false,  // user gesture | 826                         false,  // user gesture | 
| 822                         MEDIA_OPEN_DEVICE_PEPPER_ONLY, controls, salt); | 827                         MEDIA_OPEN_DEVICE_PEPPER_ONLY, controls, sc); | 
| 823 | 828 | 
| 824   const std::string& label = AddRequest(request); | 829   const std::string& label = AddRequest(request); | 
| 825   // Post a task and handle the request asynchronously. The reason is that the | 830   // Post a task and handle the request asynchronously. The reason is that the | 
| 826   // requester won't have a label for the request until this function returns | 831   // requester won't have a label for the request until this function returns | 
| 827   // and thus can not handle a response. Using base::Unretained is safe since | 832   // and thus can not handle a response. Using base::Unretained is safe since | 
| 828   // MediaStreamManager is deleted on the UI thread, after the IO thread has | 833   // MediaStreamManager is deleted on the UI thread, after the IO thread has | 
| 829   // been stopped. | 834   // been stopped. | 
| 830   BrowserThread::PostTask( | 835   BrowserThread::PostTask( | 
| 831       BrowserThread::IO, FROM_HERE, | 836       BrowserThread::IO, FROM_HERE, | 
| 832       base::Bind(&MediaStreamManager::SetupRequest, | 837       base::Bind(&MediaStreamManager::SetupRequest, | 
| 833                  base::Unretained(this), label)); | 838                  base::Unretained(this), label)); | 
| 834 } | 839 } | 
| 835 | 840 | 
| 836 bool MediaStreamManager::TranslateSourceIdToDeviceId( | 841 bool MediaStreamManager::TranslateSourceIdToDeviceId( | 
| 837     MediaStreamType stream_type, | 842     MediaStreamType stream_type, | 
| 838     const std::string& salt, | 843     const ResourceContext::SaltCallback& sc, | 
| 839     const url::Origin& security_origin, | 844     const url::Origin& security_origin, | 
| 840     const std::string& source_id, | 845     const std::string& source_id, | 
| 841     std::string* device_id) const { | 846     std::string* device_id) const { | 
| 842   DCHECK(stream_type == MEDIA_DEVICE_AUDIO_CAPTURE || | 847   DCHECK(stream_type == MEDIA_DEVICE_AUDIO_CAPTURE || | 
| 843          stream_type == MEDIA_DEVICE_VIDEO_CAPTURE); | 848          stream_type == MEDIA_DEVICE_VIDEO_CAPTURE); | 
| 844   // The source_id can be empty if the constraint is set but empty. | 849   // The source_id can be empty if the constraint is set but empty. | 
| 845   if (source_id.empty()) | 850   if (source_id.empty()) | 
| 846     return false; | 851     return false; | 
| 847 | 852 | 
| 848   const EnumerationCache* cache = | 853   const EnumerationCache* cache = | 
| 849       stream_type == MEDIA_DEVICE_AUDIO_CAPTURE ? | 854       stream_type == MEDIA_DEVICE_AUDIO_CAPTURE ? | 
| 850       &audio_enumeration_cache_ : &video_enumeration_cache_; | 855       &audio_enumeration_cache_ : &video_enumeration_cache_; | 
| 851 | 856 | 
| 852   // If device monitoring hasn't started, the |device_guid| is not valid. | 857   // If device monitoring hasn't started, the |device_guid| is not valid. | 
| 853   if (!cache->valid) | 858   if (!cache->valid) | 
| 854     return false; | 859     return false; | 
| 855 | 860 | 
| 856   for (const StreamDeviceInfo& device_info : cache->devices) { | 861   for (const StreamDeviceInfo& device_info : cache->devices) { | 
| 857     if (DoesMediaDeviceIDMatchHMAC(salt, security_origin, source_id, | 862     if (DoesMediaDeviceIDMatchHMAC(sc, security_origin, source_id, | 
| 858                                    device_info.device.id)) { | 863                                    device_info.device.id)) { | 
| 859       *device_id = device_info.device.id; | 864       *device_id = device_info.device.id; | 
| 860       return true; | 865       return true; | 
| 861     } | 866     } | 
| 862   } | 867   } | 
| 863   return false; | 868   return false; | 
| 864 } | 869 } | 
| 865 | 870 | 
| 866 void MediaStreamManager::EnsureDeviceMonitorStarted() { | 871 void MediaStreamManager::EnsureDeviceMonitorStarted() { | 
| 867   DCHECK_CURRENTLY_ON(BrowserThread::IO); | 872   DCHECK_CURRENTLY_ON(BrowserThread::IO); | 
| (...skipping 22 matching lines...) Expand all  Loading... | 
| 890     } | 895     } | 
| 891   } | 896   } | 
| 892 } | 897 } | 
| 893 | 898 | 
| 894 void MediaStreamManager::StopRemovedDevice(const MediaStreamDevice& device) { | 899 void MediaStreamManager::StopRemovedDevice(const MediaStreamDevice& device) { | 
| 895   std::vector<int> session_ids; | 900   std::vector<int> session_ids; | 
| 896   for (const LabeledDeviceRequest& labeled_request : requests_) { | 901   for (const LabeledDeviceRequest& labeled_request : requests_) { | 
| 897     const DeviceRequest* request = labeled_request.second; | 902     const DeviceRequest* request = labeled_request.second; | 
| 898     for (const StreamDeviceInfo& device_info : request->devices) { | 903     for (const StreamDeviceInfo& device_info : request->devices) { | 
| 899       const std::string source_id = GetHMACForMediaDeviceID( | 904       const std::string source_id = GetHMACForMediaDeviceID( | 
| 900           request->salt, request->security_origin, device.id); | 905           request->salt_callback, request->security_origin, device.id); | 
| 901       if (device_info.device.id == source_id && | 906       if (device_info.device.id == source_id && | 
| 902           device_info.device.type == device.type) { | 907           device_info.device.type == device.type) { | 
| 903         session_ids.push_back(device_info.session_id); | 908         session_ids.push_back(device_info.session_id); | 
| 904         if (labeled_request.second->requester) { | 909         if (labeled_request.second->requester) { | 
| 905           labeled_request.second->requester->DeviceStopped( | 910           labeled_request.second->requester->DeviceStopped( | 
| 906               labeled_request.second->requesting_frame_id, | 911               labeled_request.second->requesting_frame_id, | 
| 907               labeled_request.first, device_info); | 912               labeled_request.first, device_info); | 
| 908         } | 913         } | 
| 909       } | 914       } | 
| 910     } | 915     } | 
| (...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 979   // fixed. | 984   // fixed. | 
| 980   tracked_objects::ScopedTracker tracking_profile3( | 985   tracked_objects::ScopedTracker tracking_profile3( | 
| 981       FROM_HERE_WITH_EXPLICIT_FUNCTION( | 986       FROM_HERE_WITH_EXPLICIT_FUNCTION( | 
| 982           "458404 MediaStreamManager::DeviceMonitorMac::StartMonitoring")); | 987           "458404 MediaStreamManager::DeviceMonitorMac::StartMonitoring")); | 
| 983   browser_main_loop->device_monitor_mac()->StartMonitoring(task_runner); | 988   browser_main_loop->device_monitor_mac()->StartMonitoring(task_runner); | 
| 984 } | 989 } | 
| 985 #endif | 990 #endif | 
| 986 | 991 | 
| 987 // Pick the first valid (translatable) device ID from lists of required | 992 // Pick the first valid (translatable) device ID from lists of required | 
| 988 // and optional IDs. | 993 // and optional IDs. | 
| 989 bool MediaStreamManager::PickDeviceId(MediaStreamType type, | 994 bool MediaStreamManager::PickDeviceId( | 
| 990                                       const std::string& salt, | 995     MediaStreamType type, | 
| 991                                       const url::Origin& security_origin, | 996     const ResourceContext::SaltCallback& salt_callback, | 
| 992                                       const TrackControls& controls, | 997     const url::Origin& security_origin, | 
| 993                                       std::string* device_id) const { | 998     const TrackControls& controls, | 
|  | 999     std::string* device_id) const { | 
| 994   if (!controls.device_ids.empty()) { | 1000   if (!controls.device_ids.empty()) { | 
| 995     if (controls.device_ids.size() > 1) { | 1001     if (controls.device_ids.size() > 1) { | 
| 996       LOG(ERROR) << "Only one required device ID is supported"; | 1002       LOG(ERROR) << "Only one required device ID is supported"; | 
| 997       return false; | 1003       return false; | 
| 998     } | 1004     } | 
| 999     const std::string& candidate_id = controls.device_ids[0]; | 1005     const std::string& candidate_id = controls.device_ids[0]; | 
| 1000     if (!TranslateSourceIdToDeviceId(type, salt, security_origin, candidate_id, | 1006     if (!TranslateSourceIdToDeviceId(type, salt_callback, security_origin, | 
| 1001                                      device_id)) { | 1007                                      candidate_id, device_id)) { | 
| 1002       LOG(WARNING) << "Invalid mandatory capture ID = " << candidate_id; | 1008       LOG(WARNING) << "Invalid mandatory capture ID = " << candidate_id; | 
| 1003       return false; | 1009       return false; | 
| 1004     } | 1010     } | 
| 1005     return true; | 1011     return true; | 
| 1006   } | 1012   } | 
| 1007   // We don't have a required ID. Look at the alternates. | 1013   // We don't have a required ID. Look at the alternates. | 
| 1008   for (const std::string& candidate_id : controls.alternate_device_ids) { | 1014   for (const std::string& candidate_id : controls.alternate_device_ids) { | 
| 1009     if (TranslateSourceIdToDeviceId(type, salt, security_origin, candidate_id, | 1015     if (TranslateSourceIdToDeviceId(type, salt_callback, security_origin, | 
| 1010                                     device_id)) { | 1016                                     candidate_id, device_id)) { | 
| 1011       return true; | 1017       return true; | 
| 1012     } else { | 1018     } else { | 
| 1013       LOG(WARNING) << "Invalid optional capture ID = " << candidate_id; | 1019       LOG(WARNING) << "Invalid optional capture ID = " << candidate_id; | 
| 1014     } | 1020     } | 
| 1015   } | 1021   } | 
| 1016   return true;  // If we get here, device_id is empty. | 1022   return true;  // If we get here, device_id is empty. | 
| 1017 } | 1023 } | 
| 1018 | 1024 | 
| 1019 bool MediaStreamManager::GetRequestedDeviceCaptureId( | 1025 bool MediaStreamManager::GetRequestedDeviceCaptureId( | 
| 1020     const DeviceRequest* request, | 1026     const DeviceRequest* request, | 
| 1021     MediaStreamType type, | 1027     MediaStreamType type, | 
| 1022     std::string* device_id) const { | 1028     std::string* device_id) const { | 
| 1023   if (type == MEDIA_DEVICE_AUDIO_CAPTURE) { | 1029   if (type == MEDIA_DEVICE_AUDIO_CAPTURE) { | 
| 1024     return PickDeviceId(type, request->salt, request->security_origin, | 1030     return PickDeviceId(type, request->salt_callback, request->security_origin, | 
| 1025                         request->controls.audio, device_id); | 1031                         request->controls.audio, | 
|  | 1032                         device_id); | 
| 1026   } else if (type == MEDIA_DEVICE_VIDEO_CAPTURE) { | 1033   } else if (type == MEDIA_DEVICE_VIDEO_CAPTURE) { | 
| 1027     return PickDeviceId(type, request->salt, request->security_origin, | 1034     return PickDeviceId(type, request->salt_callback, request->security_origin, | 
| 1028                         request->controls.video, device_id); | 1035                         request->controls.video, | 
|  | 1036                         device_id); | 
| 1029   } else { | 1037   } else { | 
| 1030     NOTREACHED(); | 1038     NOTREACHED(); | 
| 1031   } | 1039   } | 
| 1032   return false; | 1040   return false; | 
| 1033 } | 1041 } | 
| 1034 | 1042 | 
| 1035 void MediaStreamManager::TranslateDeviceIdToSourceId( | 1043 void MediaStreamManager::TranslateDeviceIdToSourceId( | 
| 1036     DeviceRequest* request, | 1044     DeviceRequest* request, | 
| 1037     MediaStreamDevice* device) { | 1045     MediaStreamDevice* device) { | 
| 1038   if (request->audio_type() == MEDIA_DEVICE_AUDIO_CAPTURE || | 1046   if (request->audio_type() == MEDIA_DEVICE_AUDIO_CAPTURE || | 
| 1039       request->audio_type() == MEDIA_DEVICE_AUDIO_OUTPUT || | 1047       request->audio_type() == MEDIA_DEVICE_AUDIO_OUTPUT || | 
| 1040       request->video_type() == MEDIA_DEVICE_VIDEO_CAPTURE) { | 1048       request->video_type() == MEDIA_DEVICE_VIDEO_CAPTURE) { | 
| 1041     device->id = GetHMACForMediaDeviceID(request->salt, | 1049     device->id = GetHMACForMediaDeviceID(request->salt_callback, | 
| 1042                                          request->security_origin, device->id); | 1050                                          request->security_origin, device->id); | 
| 1043   } | 1051   } | 
| 1044 } | 1052 } | 
| 1045 | 1053 | 
| 1046 void MediaStreamManager::ClearEnumerationCache(EnumerationCache* cache) { | 1054 void MediaStreamManager::ClearEnumerationCache(EnumerationCache* cache) { | 
| 1047   DCHECK(CalledOnIOThread()); | 1055   DCHECK(CalledOnIOThread()); | 
| 1048   cache->valid = false; | 1056   cache->valid = false; | 
| 1049 } | 1057 } | 
| 1050 | 1058 | 
| 1051 bool MediaStreamManager::EnumerationRequired(EnumerationCache* cache, | 1059 bool MediaStreamManager::EnumerationRequired(EnumerationCache* cache, | 
| (...skipping 321 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 1373 } | 1381 } | 
| 1374 | 1382 | 
| 1375 bool MediaStreamManager::FindExistingRequestedDeviceInfo( | 1383 bool MediaStreamManager::FindExistingRequestedDeviceInfo( | 
| 1376     const DeviceRequest& new_request, | 1384     const DeviceRequest& new_request, | 
| 1377     const MediaStreamDevice& new_device_info, | 1385     const MediaStreamDevice& new_device_info, | 
| 1378     StreamDeviceInfo* existing_device_info, | 1386     StreamDeviceInfo* existing_device_info, | 
| 1379     MediaRequestState* existing_request_state) const { | 1387     MediaRequestState* existing_request_state) const { | 
| 1380   DCHECK(existing_device_info); | 1388   DCHECK(existing_device_info); | 
| 1381   DCHECK(existing_request_state); | 1389   DCHECK(existing_request_state); | 
| 1382 | 1390 | 
| 1383   std::string source_id = GetHMACForMediaDeviceID( | 1391   std::string source_id = | 
| 1384       new_request.salt, new_request.security_origin, new_device_info.id); | 1392       GetHMACForMediaDeviceID(new_request.salt_callback, | 
|  | 1393                               new_request.security_origin, new_device_info.id); | 
| 1385 | 1394 | 
| 1386   for (const LabeledDeviceRequest& labeled_request : requests_) { | 1395   for (const LabeledDeviceRequest& labeled_request : requests_) { | 
| 1387     const DeviceRequest* request = labeled_request.second; | 1396     const DeviceRequest* request = labeled_request.second; | 
| 1388     if (request->requesting_process_id == new_request.requesting_process_id && | 1397     if (request->requesting_process_id == new_request.requesting_process_id && | 
| 1389         request->requesting_frame_id == new_request.requesting_frame_id && | 1398         request->requesting_frame_id == new_request.requesting_frame_id && | 
| 1390         request->request_type == new_request.request_type) { | 1399         request->request_type == new_request.request_type) { | 
| 1391       for (const StreamDeviceInfo& device_info : request->devices) { | 1400       for (const StreamDeviceInfo& device_info : request->devices) { | 
| 1392         if (device_info.device.id == source_id && | 1401         if (device_info.device.id == source_id && | 
| 1393             device_info.device.type == new_device_info.type) { | 1402             device_info.device.type == new_device_info.type) { | 
| 1394           *existing_device_info = device_info; | 1403           *existing_device_info = device_info; | 
| (...skipping 722 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 2117 } | 2126 } | 
| 2118 | 2127 | 
| 2119 void MediaStreamManager::NotifyDeviceChangeSubscribers(MediaStreamType type) { | 2128 void MediaStreamManager::NotifyDeviceChangeSubscribers(MediaStreamType type) { | 
| 2120   DCHECK_CURRENTLY_ON(BrowserThread::IO); | 2129   DCHECK_CURRENTLY_ON(BrowserThread::IO); | 
| 2121   for (auto* subscriber : device_change_subscribers_) | 2130   for (auto* subscriber : device_change_subscribers_) | 
| 2122     subscriber->DevicesChanged(type); | 2131     subscriber->DevicesChanged(type); | 
| 2123 } | 2132 } | 
| 2124 | 2133 | 
| 2125 // static | 2134 // static | 
| 2126 std::string MediaStreamManager::GetHMACForMediaDeviceID( | 2135 std::string MediaStreamManager::GetHMACForMediaDeviceID( | 
| 2127     const std::string& salt, | 2136     const ResourceContext::SaltCallback& sc, | 
| 2128     const url::Origin& security_origin, | 2137     const url::Origin& security_origin, | 
| 2129     const std::string& raw_unique_id) { | 2138     const std::string& raw_unique_id) { | 
| 2130   DCHECK(!raw_unique_id.empty()); | 2139   DCHECK(!raw_unique_id.empty()); | 
| 2131   if (raw_unique_id == media::AudioDeviceDescription::kDefaultDeviceId || | 2140   if (raw_unique_id == media::AudioDeviceDescription::kDefaultDeviceId || | 
| 2132       raw_unique_id == media::AudioDeviceDescription::kCommunicationsDeviceId) { | 2141       raw_unique_id == media::AudioDeviceDescription::kCommunicationsDeviceId) { | 
| 2133     return raw_unique_id; | 2142     return raw_unique_id; | 
| 2134   } | 2143   } | 
| 2135 | 2144 | 
| 2136   crypto::HMAC hmac(crypto::HMAC::SHA256); | 2145   crypto::HMAC hmac(crypto::HMAC::SHA256); | 
| 2137   const size_t digest_length = hmac.DigestLength(); | 2146   const size_t digest_length = hmac.DigestLength(); | 
| 2138   std::vector<uint8_t> digest(digest_length); | 2147   std::vector<uint8_t> digest(digest_length); | 
|  | 2148   std::string salt = sc.Run(); | 
| 2139   bool result = hmac.Init(security_origin.Serialize()) && | 2149   bool result = hmac.Init(security_origin.Serialize()) && | 
| 2140                 hmac.Sign(raw_unique_id + salt, &digest[0], digest.size()); | 2150                 hmac.Sign(raw_unique_id + salt, &digest[0], digest.size()); | 
| 2141   DCHECK(result); | 2151   DCHECK(result); | 
| 2142   return base::ToLowerASCII(base::HexEncode(&digest[0], digest.size())); | 2152   return base::ToLowerASCII(base::HexEncode(&digest[0], digest.size())); | 
| 2143 } | 2153 } | 
| 2144 | 2154 | 
| 2145 // static | 2155 // static | 
| 2146 bool MediaStreamManager::DoesMediaDeviceIDMatchHMAC( | 2156 bool MediaStreamManager::DoesMediaDeviceIDMatchHMAC( | 
| 2147     const std::string& salt, | 2157     const ResourceContext::SaltCallback& sc, | 
| 2148     const url::Origin& security_origin, | 2158     const url::Origin& security_origin, | 
| 2149     const std::string& device_guid, | 2159     const std::string& device_guid, | 
| 2150     const std::string& raw_unique_id) { | 2160     const std::string& raw_unique_id) { | 
| 2151   DCHECK(!raw_unique_id.empty()); | 2161   DCHECK(!raw_unique_id.empty()); | 
| 2152   std::string guid_from_raw_device_id = | 2162   std::string guid_from_raw_device_id = | 
| 2153       GetHMACForMediaDeviceID(salt, security_origin, raw_unique_id); | 2163       GetHMACForMediaDeviceID(sc, security_origin, raw_unique_id); | 
| 2154   return guid_from_raw_device_id == device_guid; | 2164   return guid_from_raw_device_id == device_guid; | 
| 2155 } | 2165 } | 
| 2156 | 2166 | 
| 2157 // static | 2167 // static | 
| 2158 bool MediaStreamManager::IsOriginAllowed(int render_process_id, | 2168 bool MediaStreamManager::IsOriginAllowed(int render_process_id, | 
| 2159                                          const url::Origin& origin) { | 2169                                          const url::Origin& origin) { | 
| 2160   if (!ChildProcessSecurityPolicyImpl::GetInstance()->CanRequestURL( | 2170   if (!ChildProcessSecurityPolicyImpl::GetInstance()->CanRequestURL( | 
| 2161           render_process_id, ConvertToGURL(origin))) { | 2171           render_process_id, ConvertToGURL(origin))) { | 
| 2162     LOG(ERROR) << "MSM: Renderer requested a URL it's not allowed to use."; | 2172     LOG(ERROR) << "MSM: Renderer requested a URL it's not allowed to use."; | 
| 2163     return false; | 2173     return false; | 
| (...skipping 17 matching lines...) Expand all  Loading... | 
| 2181       if (device_info.session_id == session_id && | 2191       if (device_info.session_id == session_id && | 
| 2182           device_info.device.type == type) { | 2192           device_info.device.type == type) { | 
| 2183         request->SetCapturingLinkSecured(is_secure); | 2193         request->SetCapturingLinkSecured(is_secure); | 
| 2184         return; | 2194         return; | 
| 2185       } | 2195       } | 
| 2186     } | 2196     } | 
| 2187   } | 2197   } | 
| 2188 } | 2198 } | 
| 2189 | 2199 | 
| 2190 }  // namespace content | 2200 }  // namespace content | 
| OLD | NEW | 
|---|