media_stream_devices_controller.cc revision 46d4c2bc3267f3f028f39e7e311b0f89aba2e4fd
15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved. 25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file. 45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/media/media_stream_devices_controller.h" 65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 72a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/command_line.h" 85d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "base/metrics/histogram.h" 92a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/prefs/pref_service.h" 101e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)#include "base/prefs/scoped_user_pref_update.h" 115d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "base/strings/utf_string_conversions.h" 125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/values.h" 135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/content_settings/content_settings_provider.h" 145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/content_settings/host_content_settings_map.h" 152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "chrome/browser/content_settings/tab_specific_content_settings.h" 162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "chrome/browser/media/media_capture_devices_dispatcher.h" 17c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "chrome/browser/media/media_stream_capture_indicator.h" 185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/profiles/profile.h" 195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/ui/browser.h" 202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "chrome/common/chrome_switches.h" 21c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "chrome/common/content_settings.h" 2290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#include "chrome/common/content_settings_pattern.h" 235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/common/pref_names.h" 24cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#include "components/pref_registry/pref_registry_syncable.h" 255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/browser/browser_thread.h" 26010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)#include "content/public/browser/navigation_entry.h" 275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/common/media_stream_request.h" 28424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)#include "extensions/common/constants.h" 295d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "grit/generated_resources.h" 305d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "grit/theme_resources.h" 315d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "ui/base/l10n/l10n_util.h" 325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#if defined(OS_CHROMEOS) 34cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#include "chrome/browser/chromeos/login/users/user_manager.h" 3590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#endif 3690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using content::BrowserThread; 385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace { 405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 41010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)// This prefix is combined with request security origins to store media access 42010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)// permissions that the user has granted a specific page navigation instance. 43010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)// The string value stored with the navigation instance will contain one or more 44010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)// kMediaPermissionXxx constants that indicates the permission(s) that the user 45010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)// has granted the page. 46010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)const char kMediaPermissionKeyPrefix[] = "media_permissions#"; 47010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)const base::char16 kMediaPermissionAudio = static_cast<base::char16>('a'); 48010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)const base::char16 kMediaPermissionVideo = static_cast<base::char16>('v'); 49010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) 50effb81e5f8246d0db0270817048dc992db66e9fbBen Murdochbool HasAvailableDevicesForRequest(const content::MediaStreamRequest& request) { 51010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) const content::MediaStreamDevices* audio_devices = 52010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) request.audio_type == content::MEDIA_DEVICE_AUDIO_CAPTURE ? 53010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) &MediaCaptureDevicesDispatcher::GetInstance() 54010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) ->GetAudioCaptureDevices() : 55010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) NULL; 56010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) 57010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) const content::MediaStreamDevices* video_devices = 58010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) request.video_type == content::MEDIA_DEVICE_VIDEO_CAPTURE ? 59010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) &MediaCaptureDevicesDispatcher::GetInstance() 60010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) ->GetVideoCaptureDevices() : 61010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) NULL; 62010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) 63010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) // Check if we're being asked for audio and/or video and that either of those 64010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) // lists is empty. If they are, we do not have devices available for the 65010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) // request. 66010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) // TODO(tommi): It's kind of strange to have this here since if we fail this 67010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) // test, there'll be a UI shown that indicates to the user that access to 68010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) // non-existing audio/video devices has been denied. The user won't have 69010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) // any way to change that but there will be a UI shown which indicates that 70010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) // access is blocked. 71010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) if ((audio_devices != NULL && audio_devices->empty()) || 72010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) (video_devices != NULL && video_devices->empty())) { 73010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) return false; 74010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) } 75010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) 76010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) // Note: we check requested_[audio|video]_device_id before dereferencing 77010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) // [audio|video]_devices. If the requested device id is non-empty, then 78010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) // the corresponding device list must not be NULL. 79010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) 80010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) if (!request.requested_audio_device_id.empty() && 81010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) !audio_devices->FindById(request.requested_audio_device_id)) { 82010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) return false; 83010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) } 84010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) 85010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) if (!request.requested_video_device_id.empty() && 86010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) !video_devices->FindById(request.requested_video_device_id)) { 87010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) return false; 88010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) } 89010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) 90010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) return true; 91010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)} 92010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) 93010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)base::string16 GetMediaPermissionsFromNavigationEntry( 94010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) content::NavigationEntry* navigation_entry, 95010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) const content::MediaStreamRequest& request) { 96010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) const std::string key(kMediaPermissionKeyPrefix + 97010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) request.security_origin.spec()); 98010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) 99010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) base::string16 permissions; 100010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) if (!navigation_entry->GetExtraData(key, &permissions)) { 101010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) DCHECK(permissions.empty()); 102010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) } 103010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) 104010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) return permissions; 105010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)} 106010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) 107010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)void SetMediaPermissionsForNavigationEntry( 108010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) content::NavigationEntry* navigation_entry, 109010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) const content::MediaStreamRequest& request, 110010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) const base::string16& permissions) { 111010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) const std::string key(kMediaPermissionKeyPrefix + 112010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) request.security_origin.spec()); 113010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) permissions.empty() ? 114010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) navigation_entry->ClearExtraData(key) : 115010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) navigation_entry->SetExtraData(key, permissions); 116010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)} 117effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch 118010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)void SetMediaPermissionsForNavigationEntry( 119010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) content::NavigationEntry* navigation_entry, 120010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) const content::MediaStreamRequest& request, 121010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) bool allow_audio, 122010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) bool allow_video) { 123010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) base::string16 permissions; 124010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) if (allow_audio) 125010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) permissions += kMediaPermissionAudio; 126010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) if (allow_video) 127010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) permissions += kMediaPermissionVideo; 128010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) SetMediaPermissionsForNavigationEntry(navigation_entry, request, permissions); 12990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)} 13090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 131010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)bool IsRequestAllowedByNavigationEntry( 132010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) content::NavigationEntry* navigation_entry, 133010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) const content::MediaStreamRequest& request) { 134010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) using content::MEDIA_NO_SERVICE; 135010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) using content::MEDIA_DEVICE_AUDIO_CAPTURE; 136010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) using content::MEDIA_DEVICE_VIDEO_CAPTURE; 137010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) 138010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) // If we aren't being asked for at least one of these two, fail right away. 139010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) if (!navigation_entry || 140010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) (request.audio_type != MEDIA_DEVICE_AUDIO_CAPTURE && 141010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) request.video_type != MEDIA_DEVICE_VIDEO_CAPTURE)) { 142010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) return false; 143010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) } 144010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) 145010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) base::string16 permissions = 146010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) GetMediaPermissionsFromNavigationEntry(navigation_entry, request); 147010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) 148010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) bool audio_requested_and_granted = 149010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) request.audio_type == MEDIA_DEVICE_AUDIO_CAPTURE && 150010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) permissions.find(kMediaPermissionAudio) != base::string16::npos; 151010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) 152010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) bool video_requested_and_granted = 153010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) request.video_type == MEDIA_DEVICE_VIDEO_CAPTURE && 154010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) permissions.find(kMediaPermissionVideo) != base::string16::npos; 155010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) 156010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) return 157010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) (audio_requested_and_granted || request.audio_type == MEDIA_NO_SERVICE) && 158010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) (video_requested_and_granted || request.video_type == MEDIA_NO_SERVICE); 159010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)} 160010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) 161010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) 16290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)bool IsInKioskMode() { 16390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) if (CommandLine::ForCurrentProcess()->HasSwitch(switches::kKioskMode)) 16490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) return true; 16590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 16690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#if defined(OS_CHROMEOS) 16790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) const chromeos::UserManager* user_manager = chromeos::UserManager::Get(); 16890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) return user_manager && user_manager->IsLoggedInAsKioskApp(); 16990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#else 17090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) return false; 17190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#endif 17290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)} 1735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1745d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)enum DevicePermissionActions { 1755d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) kAllowHttps = 0, 1765d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) kAllowHttp, 1775d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) kDeny, 1785d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) kCancel, 1795d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) kPermissionActionsMax // Must always be last! 1805d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}; 1815d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 1825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} // namespace 1835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 18468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)MediaStreamDevicesController::MediaStreamTypeSettings::MediaStreamTypeSettings( 18568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) Permission permission, const std::string& requested_device_id): 18668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) permission(permission), requested_device_id(requested_device_id) {} 18768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) 18868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)MediaStreamDevicesController::MediaStreamTypeSettings:: 18968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) MediaStreamTypeSettings(): permission(MEDIA_NONE) {} 19068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) 19168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)MediaStreamDevicesController::MediaStreamTypeSettings:: 19268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) ~MediaStreamTypeSettings() {} 19368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) 1945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)MediaStreamDevicesController::MediaStreamDevicesController( 195c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) content::WebContents* web_contents, 1962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const content::MediaStreamRequest& request, 1975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const content::MediaResponseCallback& callback) 198c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) : web_contents_(web_contents), 1992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) request_(request), 2003551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) callback_(callback) { 201c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) profile_ = Profile::FromBrowserContext(web_contents->GetBrowserContext()); 202c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) content_settings_ = TabSpecificContentSettings::FromWebContents(web_contents); 203c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 2043551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) // For MEDIA_OPEN_DEVICE requests (Pepper) we always request both webcam 2053551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) // and microphone to avoid popping two infobars. 2063551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) // We start with setting the requested media type to allowed or blocked 2073551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) // depending on the policy. If not blocked by policy it may be blocked later 2083551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) // in the two remaining filtering steps (by user setting or by user when 2093551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) // clicking the infobar). 2103551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) // TODO(grunell): It's not the nicest solution to let the MEDIA_OPEN_DEVICE 2113551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) // case take a ride on the MEDIA_DEVICE_*_CAPTURE permission. Should be fixed. 2123551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) if (request.audio_type == content::MEDIA_DEVICE_AUDIO_CAPTURE || 2133551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) request.request_type == content::MEDIA_OPEN_DEVICE) { 2143551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) if (GetDevicePolicy(prefs::kAudioCaptureAllowed, 2153551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) prefs::kAudioCaptureAllowedUrls) == ALWAYS_DENY) { 21668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) request_permissions_.insert(std::make_pair( 21768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) content::MEDIA_DEVICE_AUDIO_CAPTURE, 21868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) MediaStreamTypeSettings(MEDIA_BLOCKED_BY_POLICY, 21968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) request.requested_audio_device_id))); 2203551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) } else { 22168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) request_permissions_.insert(std::make_pair( 22268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) content::MEDIA_DEVICE_AUDIO_CAPTURE, 22368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) MediaStreamTypeSettings(MEDIA_ALLOWED, 22468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) request.requested_audio_device_id))); 2253551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) } 226c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 2273551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) if (request.video_type == content::MEDIA_DEVICE_VIDEO_CAPTURE || 2283551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) request.request_type == content::MEDIA_OPEN_DEVICE) { 2293551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) if (GetDevicePolicy(prefs::kVideoCaptureAllowed, 2303551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) prefs::kVideoCaptureAllowedUrls) == ALWAYS_DENY) { 23168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) request_permissions_.insert(std::make_pair( 23268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) content::MEDIA_DEVICE_VIDEO_CAPTURE, 23368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) MediaStreamTypeSettings(MEDIA_BLOCKED_BY_POLICY, 23468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) request.requested_video_device_id))); 2353551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) } else { 23668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) request_permissions_.insert(std::make_pair( 23768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) content::MEDIA_DEVICE_VIDEO_CAPTURE, 23868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) MediaStreamTypeSettings(MEDIA_ALLOWED, 23968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) request.requested_video_device_id))); 2403551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) } 241c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 2425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 244868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)MediaStreamDevicesController::~MediaStreamDevicesController() { 245868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) if (!callback_.is_null()) { 246868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) callback_.Run(content::MediaStreamDevices(), 247a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) content::MEDIA_DEVICE_INVALID_STATE, 248868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) scoped_ptr<content::MediaStreamUI>()); 249868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) } 250868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)} 2515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// static 2537dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdochvoid MediaStreamDevicesController::RegisterProfilePrefs( 254c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) user_prefs::PrefRegistrySyncable* prefs) { 2552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) prefs->RegisterBooleanPref(prefs::kVideoCaptureAllowed, 2562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) true, 257c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF); 2582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) prefs->RegisterBooleanPref(prefs::kAudioCaptureAllowed, 2592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) true, 260c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF); 26190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) prefs->RegisterListPref(prefs::kVideoCaptureAllowedUrls, 26290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF); 26390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) prefs->RegisterListPref(prefs::kAudioCaptureAllowedUrls, 26490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF); 2652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 2662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2675d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// TODO(gbillock): rename? doesn't actually dismiss. More of a 'check profile 2685d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// and system for compatibility' thing. 269c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)bool MediaStreamDevicesController::DismissInfoBarAndTakeActionOnSettings() { 270c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // Tab capture is allowed for extensions only and infobar is not shown for 271c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // extensions. 272c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (request_.audio_type == content::MEDIA_TAB_AUDIO_CAPTURE || 273c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) request_.video_type == content::MEDIA_TAB_VIDEO_CAPTURE) { 274a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) Deny(false, content::MEDIA_DEVICE_INVALID_STATE); 275c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return true; 276c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 2775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 278c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // Deny the request if the security origin is empty, this happens with 279c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // file access without |--allow-file-access-from-files| flag. 280c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (request_.security_origin.is_empty()) { 281a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) Deny(false, content::MEDIA_DEVICE_INVALID_SECURITY_ORIGIN); 282c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return true; 2835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 285effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch // Deny the request if there is no device attached to the OS of the 286effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch // requested type. If both audio and video is requested, both types must be 287effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch // available. 288effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch if (!HasAvailableDevicesForRequest(request_)) { 289a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) Deny(false, content::MEDIA_DEVICE_NO_HARDWARE); 290c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return true; 2912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 2925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 293c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // Check if any allow exception has been made for this request. 294c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (IsRequestAllowedByDefault()) { 295c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) Accept(false); 2962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return true; 2975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2997dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch // Filter any parts of the request that have been blocked by default and deny 3007dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch // it if nothing is left to accept. 3017dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch if (FilterBlockedByDefaultDevices() == 0) { 302a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) Deny(false, content::MEDIA_DEVICE_PERMISSION_DENIED); 3032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return true; 3042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 3055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 306c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // Check if the media default setting is set to block. 307c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (IsDefaultMediaAccessBlocked()) { 308a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) Deny(false, content::MEDIA_DEVICE_PERMISSION_DENIED); 3092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return true; 3102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 3115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 312010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) // Check if the navigation entry has previously been granted access. 313010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) // We do this after the IsDefaultMediaAccessBlocked check to handle the use 314010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) // case where the user modifies the content settings to 'deny' after having 315010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) // previously granted the page access and the permissions in the 316010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) // NavigationEntry are out of date. 317010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) content::NavigationEntry* navigation_entry = 318010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) web_contents_->GetController().GetVisibleEntry(); 319010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) if (IsRequestAllowedByNavigationEntry(navigation_entry, request_)) { 320010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) Accept(false); 321010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) return true; 32268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) } 32368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) 324c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // Show the infobar. 3252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return false; 3265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3283551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)bool MediaStreamDevicesController::HasAudio() const { 3293551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) return IsDeviceAudioCaptureRequestedAndAllowed(); 3303551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)} 3313551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 3323551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)bool MediaStreamDevicesController::HasVideo() const { 3333551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) return IsDeviceVideoCaptureRequestedAndAllowed(); 3343551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)} 3353551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 336c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)const std::string& MediaStreamDevicesController::GetSecurityOriginSpec() const { 337c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return request_.security_origin.spec(); 3385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 340c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void MediaStreamDevicesController::Accept(bool update_content_setting) { 3417d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) NotifyUIRequestAccepted(); 3425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 343c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // Get the default devices for the request. 344c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) content::MediaStreamDevices devices; 3453551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) bool audio_allowed = IsDeviceAudioCaptureRequestedAndAllowed(); 3463551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) bool video_allowed = IsDeviceVideoCaptureRequestedAndAllowed(); 3473551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) if (audio_allowed || video_allowed) { 348c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) switch (request_.request_type) { 3497dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch case content::MEDIA_OPEN_DEVICE: { 3507dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch const content::MediaStreamDevice* device = NULL; 35168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) // For open device request, when requested device_id is empty, pick 35268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) // the first available of the given type. If requested device_id is 35368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) // not empty, return the desired device if it's available. Otherwise, 35468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) // return no device. 35558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) if (audio_allowed && 35658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) request_.audio_type == content::MEDIA_DEVICE_AUDIO_CAPTURE) { 35768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) if (!request_.requested_audio_device_id.empty()) { 35868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) device = MediaCaptureDevicesDispatcher::GetInstance()-> 35968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) GetRequestedAudioDevice(request_.requested_audio_device_id); 36068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) } else { 3617dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch device = MediaCaptureDevicesDispatcher::GetInstance()-> 3627dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch GetFirstAvailableAudioDevice(); 3637dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch } 36458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) } else if (video_allowed && 36558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) request_.video_type == content::MEDIA_DEVICE_VIDEO_CAPTURE) { 3667dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch // Pepper API opens only one device at a time. 36768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) if (!request_.requested_video_device_id.empty()) { 36868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) device = MediaCaptureDevicesDispatcher::GetInstance()-> 36968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) GetRequestedVideoDevice(request_.requested_video_device_id); 37068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) } else { 3717dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch device = MediaCaptureDevicesDispatcher::GetInstance()-> 3727dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch GetFirstAvailableVideoDevice(); 3737dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch } 3747dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch } 3757dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch if (device) 3767dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch devices.push_back(*device); 377c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) break; 37858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) } 37958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) case content::MEDIA_GENERATE_STREAM: { 38058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) bool get_default_audio_device = audio_allowed; 38158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) bool get_default_video_device = video_allowed; 3827dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch 3837dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch // Get the exact audio or video device if an id is specified. 38458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) if (audio_allowed && !request_.requested_audio_device_id.empty()) { 3857dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch const content::MediaStreamDevice* audio_device = 3867dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch MediaCaptureDevicesDispatcher::GetInstance()-> 3877dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch GetRequestedAudioDevice(request_.requested_audio_device_id); 3887dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch if (audio_device) { 3897dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch devices.push_back(*audio_device); 39058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) get_default_audio_device = false; 3917dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch } 3927dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch } 39358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) if (video_allowed && !request_.requested_video_device_id.empty()) { 3947dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch const content::MediaStreamDevice* video_device = 3957dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch MediaCaptureDevicesDispatcher::GetInstance()-> 3967dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch GetRequestedVideoDevice(request_.requested_video_device_id); 3977dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch if (video_device) { 3987dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch devices.push_back(*video_device); 39958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) get_default_video_device = false; 4007dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch } 4017dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch } 4027dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch 4037dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch // If either or both audio and video devices were requested but not 4047dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch // specified by id, get the default devices. 40558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) if (get_default_audio_device || get_default_video_device) { 4067dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch MediaCaptureDevicesDispatcher::GetInstance()-> 4077dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch GetDefaultDevicesForProfile(profile_, 40858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) get_default_audio_device, 40958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) get_default_video_device, 4107dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch &devices); 4117dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch } 412010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) 413cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) // For pages accessed via http (not https), tag this navigation entry 414cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) // with the granted permissions. This avoids repeated prompts for 415cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) // device access. 416cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) if (!IsSchemeSecure()) { 417cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) content::NavigationEntry* navigation_entry = 418cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) web_contents_->GetController().GetVisibleEntry(); 419cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) if (navigation_entry) { 420cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) SetMediaPermissionsForNavigationEntry( 421cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) navigation_entry, request_, audio_allowed, video_allowed); 422cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) } 423010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) } 4247dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch break; 42558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) } 42658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) case content::MEDIA_DEVICE_ACCESS: { 427c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // Get the default devices for the request. 428c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) MediaCaptureDevicesDispatcher::GetInstance()-> 429c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) GetDefaultDevicesForProfile(profile_, 4303551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) audio_allowed, 4313551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) video_allowed, 432c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) &devices); 433c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) break; 43458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) } 43558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) case content::MEDIA_ENUMERATE_DEVICES: { 4367dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch // Do nothing. 4377dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch NOTREACHED(); 4387dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch break; 43958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) } 44058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) } // switch 441c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 4427d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) // TODO(raymes): We currently set the content permission for non-https 4437d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) // websites for Pepper requests as well. This is temporary and should be 4447d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) // removed. 4457d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) if (update_content_setting) { 4467d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) if ((IsSchemeSecure() && !devices.empty()) || 4477d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) request_.request_type == content::MEDIA_OPEN_DEVICE) { 4487d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) SetPermission(true); 4497d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) } 4507d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) } 4515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 453c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) scoped_ptr<content::MediaStreamUI> ui; 454c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (!devices.empty()) { 455c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) ui = MediaCaptureDevicesDispatcher::GetInstance()-> 456c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) GetMediaStreamCaptureIndicator()->RegisterMediaStream( 457c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) web_contents_, devices); 458c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 459868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) content::MediaResponseCallback cb = callback_; 460868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) callback_.Reset(); 461e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch cb.Run(devices, 462e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch devices.empty() ? 463e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch content::MEDIA_DEVICE_NO_HARDWARE : content::MEDIA_DEVICE_OK, 464e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch ui.Pass()); 4655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 467a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)void MediaStreamDevicesController::Deny( 468a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) bool update_content_setting, 469a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) content::MediaStreamRequestResult result) { 470a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) DLOG(WARNING) << "MediaStreamDevicesController::Deny: " << result; 4717d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) NotifyUIRequestDenied(); 4725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 473010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) // Clear previously allowed permissions from the navigation entry if any. 474010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) content::NavigationEntry* navigation_entry = 475010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) web_contents_->GetController().GetVisibleEntry(); 476010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) if (navigation_entry) { 477010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) SetMediaPermissionsForNavigationEntry( 478010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) navigation_entry, request_, false, false); 479010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) } 480010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) 481010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) if (update_content_setting) { 482010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) CHECK_EQ(content::MEDIA_DEVICE_PERMISSION_DENIED, result); 483c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) SetPermission(false); 484010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) } 4855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 486868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) content::MediaResponseCallback cb = callback_; 487868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) callback_.Reset(); 488a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) cb.Run(content::MediaStreamDevices(), 489a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) result, 490a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) scoped_ptr<content::MediaStreamUI>()); 491a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)} 492a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 493a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)int MediaStreamDevicesController::GetIconID() const { 494a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) if (HasVideo()) 495a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) return IDR_INFOBAR_MEDIA_STREAM_CAMERA; 496a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 497a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) return IDR_INFOBAR_MEDIA_STREAM_MIC; 4985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5005d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)base::string16 MediaStreamDevicesController::GetMessageText() const { 5015d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) int message_id = IDS_MEDIA_CAPTURE_AUDIO_AND_VIDEO; 5025d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (!HasAudio()) 5035d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) message_id = IDS_MEDIA_CAPTURE_VIDEO_ONLY; 5045d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) else if (!HasVideo()) 5055d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) message_id = IDS_MEDIA_CAPTURE_AUDIO_ONLY; 5065d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) return l10n_util::GetStringFUTF16( 5075d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) message_id, base::UTF8ToUTF16(GetSecurityOriginSpec())); 5085d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)} 5095d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 5105d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)base::string16 MediaStreamDevicesController::GetMessageTextFragment() const { 5115d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) int message_id = IDS_MEDIA_CAPTURE_AUDIO_AND_VIDEO_PERMISSION_FRAGMENT; 5125d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (!HasAudio()) 5135d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) message_id = IDS_MEDIA_CAPTURE_VIDEO_ONLY_PERMISSION_FRAGMENT; 5145d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) else if (!HasVideo()) 5155d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) message_id = IDS_MEDIA_CAPTURE_AUDIO_ONLY_PERMISSION_FRAGMENT; 5165d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) return l10n_util::GetStringUTF16(message_id); 5175d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)} 5185d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 519a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)bool MediaStreamDevicesController::HasUserGesture() const { 520effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch return request_.user_gesture; 5215d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)} 5225d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 523a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)GURL MediaStreamDevicesController::GetRequestingHostname() const { 524a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) return request_.security_origin; 5255d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)} 5265d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 5275d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void MediaStreamDevicesController::PermissionGranted() { 5285d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) GURL origin(GetSecurityOriginSpec()); 5295d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (origin.SchemeIsSecure()) { 5305d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) UMA_HISTOGRAM_ENUMERATION("Media.DevicePermissionActions", 5315d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) kAllowHttps, kPermissionActionsMax); 5325d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } else { 5335d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) UMA_HISTOGRAM_ENUMERATION("Media.DevicePermissionActions", 5345d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) kAllowHttp, kPermissionActionsMax); 5355d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 5365d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) Accept(true); 5375d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)} 5385d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 5395d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void MediaStreamDevicesController::PermissionDenied() { 5405d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) UMA_HISTOGRAM_ENUMERATION("Media.DevicePermissionActions", 5415d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) kDeny, kPermissionActionsMax); 542a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) Deny(true, content::MEDIA_DEVICE_PERMISSION_DENIED); 5435d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)} 5445d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 5455d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void MediaStreamDevicesController::Cancelled() { 5465d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) UMA_HISTOGRAM_ENUMERATION("Media.DevicePermissionActions", 5475d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) kCancel, kPermissionActionsMax); 548010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) Deny(false, content::MEDIA_DEVICE_PERMISSION_DISMISSED); 5495d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)} 5505d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 5515d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void MediaStreamDevicesController::RequestFinished() { 5525d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) delete this; 5535d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)} 5545d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 555c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)MediaStreamDevicesController::DevicePolicy 55690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)MediaStreamDevicesController::GetDevicePolicy( 55790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) const char* policy_name, 55890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) const char* whitelist_policy_name) const { 559c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 5602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 56190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // If the security origin policy matches a value in the whitelist, allow it. 56290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // Otherwise, check the |policy_name| master switch for the default behavior. 56390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 564c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) PrefService* prefs = profile_->GetPrefs(); 5652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 56690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // TODO(tommi): Remove the kiosk mode check when the whitelist below 56790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // is visible in the media exceptions UI. 56890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // See discussion here: https://codereview.chromium.org/15738004/ 56990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) if (IsInKioskMode()) { 57090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) const base::ListValue* list = prefs->GetList(whitelist_policy_name); 57190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) std::string value; 57290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) for (size_t i = 0; i < list->GetSize(); ++i) { 57390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) if (list->GetString(i, &value)) { 57490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) ContentSettingsPattern pattern = 57590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) ContentSettingsPattern::FromString(value); 57690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) if (pattern == ContentSettingsPattern::Wildcard()) { 57790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) DLOG(WARNING) << "Ignoring wildcard URL pattern: " << value; 57890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) continue; 57990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) } 58090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) DLOG_IF(ERROR, !pattern.IsValid()) << "Invalid URL pattern: " << value; 58190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) if (pattern.IsValid() && pattern.Matches(request_.security_origin)) 58290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) return ALWAYS_ALLOW; 58390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) } 58490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) } 58590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) } 58690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 58790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // If a match was not found, check if audio capture is otherwise disallowed 58890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // or if the user should be prompted. Setting the policy value to "true" 58990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // is equal to not setting it at all, so from hereon out, we will return 59090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // either POLICY_NOT_SET (prompt) or ALWAYS_DENY (no prompt, no access). 59190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) if (!prefs->GetBoolean(policy_name)) 59290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) return ALWAYS_DENY; 59390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 59490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) return POLICY_NOT_SET; 595c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 596c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 597c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)bool MediaStreamDevicesController::IsRequestAllowedByDefault() const { 598c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // The request from internal objects like chrome://URLs is always allowed. 599c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (ShouldAlwaysAllowOrigin()) 600c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return true; 601c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 602c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) struct { 603c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) bool has_capability; 604c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const char* policy_name; 60590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) const char* list_policy_name; 606c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) ContentSettingsType settings_type; 607c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } device_checks[] = { 6083551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) { IsDeviceAudioCaptureRequestedAndAllowed(), prefs::kAudioCaptureAllowed, 60990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) prefs::kAudioCaptureAllowedUrls, CONTENT_SETTINGS_TYPE_MEDIASTREAM_MIC }, 6103551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) { IsDeviceVideoCaptureRequestedAndAllowed(), prefs::kVideoCaptureAllowed, 61190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) prefs::kVideoCaptureAllowedUrls, 612c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) CONTENT_SETTINGS_TYPE_MEDIASTREAM_CAMERA }, 613c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) }; 614c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 615c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) for (size_t i = 0; i < ARRAYSIZE_UNSAFE(device_checks); ++i) { 616c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (!device_checks[i].has_capability) 617c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) continue; 618c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 61990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) DevicePolicy policy = GetDevicePolicy(device_checks[i].policy_name, 62090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) device_checks[i].list_policy_name); 6217d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) 6227d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) if (policy == ALWAYS_DENY) 623c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return false; 6247d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) 6257d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) if (policy == POLICY_NOT_SET) { 6267d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) // Only load content settings from secure origins unless it is a 6277d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) // content::MEDIA_OPEN_DEVICE (Pepper) request. 6287d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) if (!IsSchemeSecure() && 6297d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) request_.request_type != content::MEDIA_OPEN_DEVICE) { 6307d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) return false; 6317d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) } 6327d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) if (profile_->GetHostContentSettingsMap()->GetContentSetting( 6337d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) request_.security_origin, request_.security_origin, 6347d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) device_checks[i].settings_type, NO_RESOURCE_IDENTIFIER) != 6357d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) CONTENT_SETTING_ALLOW) { 6367d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) return false; 6377d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) } 6382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 639c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // If we get here, then either policy is set to ALWAYS_ALLOW or the content 640c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // settings allow the request by default. 6415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 6425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 643c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return true; 644c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 6455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6467dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdochint MediaStreamDevicesController::FilterBlockedByDefaultDevices() { 6473551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) int requested_devices = 0; 6483551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 6493551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) if (IsDeviceAudioCaptureRequestedAndAllowed()) { 6503551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) if (profile_->GetHostContentSettingsMap()->GetContentSetting( 6513551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) request_.security_origin, 6523551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) request_.security_origin, 6533551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) CONTENT_SETTINGS_TYPE_MEDIASTREAM_MIC, 6543551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) NO_RESOURCE_IDENTIFIER) == CONTENT_SETTING_BLOCK) { 65568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) request_permissions_[content::MEDIA_DEVICE_AUDIO_CAPTURE].permission = 6563551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) MEDIA_BLOCKED_BY_USER_SETTING; 6573551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) } else { 6583551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) ++requested_devices; 6593551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) } 6605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 6615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6623551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) if (IsDeviceVideoCaptureRequestedAndAllowed()) { 6633551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) if (profile_->GetHostContentSettingsMap()->GetContentSetting( 6643551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) request_.security_origin, 6653551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) request_.security_origin, 6663551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) CONTENT_SETTINGS_TYPE_MEDIASTREAM_CAMERA, 6673551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) NO_RESOURCE_IDENTIFIER) == CONTENT_SETTING_BLOCK) { 66868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) request_permissions_[content::MEDIA_DEVICE_VIDEO_CAPTURE].permission = 6693551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) MEDIA_BLOCKED_BY_USER_SETTING; 6703551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) } else { 6713551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) ++requested_devices; 6723551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) } 6735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 674c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 6757dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch return requested_devices; 6765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 6775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 678c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)bool MediaStreamDevicesController::IsDefaultMediaAccessBlocked() const { 679c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 680c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // TODO(markusheintz): Replace CONTENT_SETTINGS_TYPE_MEDIA_STREAM with the 681c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // appropriate new CONTENT_SETTINGS_TYPE_MEDIASTREAM_MIC and 682c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // CONTENT_SETTINGS_TYPE_MEDIASTREAM_CAMERA. 683c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) ContentSetting current_setting = 684c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) profile_->GetHostContentSettingsMap()->GetDefaultContentSetting( 685c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) CONTENT_SETTINGS_TYPE_MEDIASTREAM, NULL); 686c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return (current_setting == CONTENT_SETTING_BLOCK); 687c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 688c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 689c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)bool MediaStreamDevicesController::IsSchemeSecure() const { 690424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) return request_.security_origin.SchemeIsSecure() || 69146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) request_.security_origin.SchemeIs(extensions::kExtensionScheme); 692c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 693c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 694c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)bool MediaStreamDevicesController::ShouldAlwaysAllowOrigin() const { 695c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // TODO(markusheintz): Replace CONTENT_SETTINGS_TYPE_MEDIA_STREAM with the 696c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // appropriate new CONTENT_SETTINGS_TYPE_MEDIASTREAM_MIC and 697c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // CONTENT_SETTINGS_TYPE_MEDIASTREAM_CAMERA. 698c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return profile_->GetHostContentSettingsMap()->ShouldAllowAllContent( 699c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) request_.security_origin, request_.security_origin, 700c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) CONTENT_SETTINGS_TYPE_MEDIASTREAM); 701c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 702c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 703c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void MediaStreamDevicesController::SetPermission(bool allowed) const { 704c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 705c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) ContentSettingsPattern primary_pattern = 706c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) ContentSettingsPattern::FromURLNoWildcard(request_.security_origin); 707c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // Check the pattern is valid or not. When the request is from a file access, 708c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // no exception will be made. 709c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (!primary_pattern.IsValid()) 710c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return; 7115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 712c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) ContentSetting content_setting = allowed ? 713c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) CONTENT_SETTING_ALLOW : CONTENT_SETTING_BLOCK; 7143551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) if (request_permissions_.find(content::MEDIA_DEVICE_AUDIO_CAPTURE) != 7153551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) request_permissions_.end()) { 716010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) profile_->GetHostContentSettingsMap()->SetContentSetting( 717c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) primary_pattern, 718c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) ContentSettingsPattern::Wildcard(), 719c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) CONTENT_SETTINGS_TYPE_MEDIASTREAM_MIC, 720c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) std::string(), 721c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) content_setting); 722c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 7233551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) if (request_permissions_.find(content::MEDIA_DEVICE_VIDEO_CAPTURE) != 7243551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) request_permissions_.end()) { 725c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) profile_->GetHostContentSettingsMap()->SetContentSetting( 726c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) primary_pattern, 727c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) ContentSettingsPattern::Wildcard(), 728c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) CONTENT_SETTINGS_TYPE_MEDIASTREAM_CAMERA, 729c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) std::string(), 730c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) content_setting); 731c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 7325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 7337d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) 7347d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)void MediaStreamDevicesController::NotifyUIRequestAccepted() const { 7357d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) if (!content_settings_) 7367d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) return; 7377d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) 7383551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) content_settings_->OnMediaStreamPermissionSet(request_.security_origin, 7393551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) request_permissions_); 7407d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)} 7417d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) 7423551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)void MediaStreamDevicesController::NotifyUIRequestDenied() { 7437d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) if (!content_settings_) 7447d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) return; 7457d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) 7463551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) if (IsDeviceAudioCaptureRequestedAndAllowed()) { 74768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) request_permissions_[content::MEDIA_DEVICE_AUDIO_CAPTURE].permission = 7483551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) MEDIA_BLOCKED_BY_USER; 7497d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) } 7503551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) if (IsDeviceVideoCaptureRequestedAndAllowed()) { 75168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) request_permissions_[content::MEDIA_DEVICE_VIDEO_CAPTURE].permission = 7523551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) MEDIA_BLOCKED_BY_USER; 7533551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) } 7543551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 7553551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) content_settings_->OnMediaStreamPermissionSet(request_.security_origin, 7563551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) request_permissions_); 7573551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)} 7583551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 7593551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)bool MediaStreamDevicesController::IsDeviceAudioCaptureRequestedAndAllowed() 7603551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) const { 76168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) MediaStreamTypeSettingsMap::const_iterator it = 7623551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) request_permissions_.find(content::MEDIA_DEVICE_AUDIO_CAPTURE); 76368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) return (it != request_permissions_.end() && 76468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) it->second.permission == MEDIA_ALLOWED); 7653551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)} 7667d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) 7673551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)bool MediaStreamDevicesController::IsDeviceVideoCaptureRequestedAndAllowed() 7683551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) const { 76968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) MediaStreamTypeSettingsMap::const_iterator it = 7703551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) request_permissions_.find(content::MEDIA_DEVICE_VIDEO_CAPTURE); 77168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) return (it != request_permissions_.end() && 77268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) it->second.permission == MEDIA_ALLOWED); 7737d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)} 774