1 // Copyright 2016 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 #include "chrome/browser/media/public_session_media_access_handler.h"
6 
7 #include <set>
8 #include <utility>
9 
10 #include "base/bind.h"
11 #include "base/callback_helpers.h"
12 #include "chrome/browser/chromeos/extensions/public_session_permission_helper.h"
13 #include "chrome/browser/profiles/profiles_state.h"
14 #include "chromeos/login/login_state/login_state.h"
15 #include "content/public/browser/web_contents.h"
16 #include "extensions/common/extension.h"
17 #include "extensions/common/permissions/manifest_permission_set.h"
18 #include "extensions/common/permissions/permission_set.h"
19 #include "extensions/common/url_pattern_set.h"
20 
PublicSessionMediaAccessHandler()21 PublicSessionMediaAccessHandler::PublicSessionMediaAccessHandler() {}
22 
~PublicSessionMediaAccessHandler()23 PublicSessionMediaAccessHandler::~PublicSessionMediaAccessHandler() {}
24 
SupportsStreamType(content::WebContents * web_contents,const blink::mojom::MediaStreamType type,const extensions::Extension * extension)25 bool PublicSessionMediaAccessHandler::SupportsStreamType(
26     content::WebContents* web_contents,
27     const blink::mojom::MediaStreamType type,
28     const extensions::Extension* extension) {
29   return extension_media_access_handler_.SupportsStreamType(web_contents, type,
30                                                             extension);
31 }
32 
CheckMediaAccessPermission(content::RenderFrameHost * render_frame_host,const GURL & security_origin,blink::mojom::MediaStreamType type,const extensions::Extension * extension)33 bool PublicSessionMediaAccessHandler::CheckMediaAccessPermission(
34     content::RenderFrameHost* render_frame_host,
35     const GURL& security_origin,
36     blink::mojom::MediaStreamType type,
37     const extensions::Extension* extension) {
38   return extension_media_access_handler_.CheckMediaAccessPermission(
39       render_frame_host, security_origin, type, extension);
40 }
41 
HandleRequest(content::WebContents * web_contents,const content::MediaStreamRequest & request,content::MediaResponseCallback callback,const extensions::Extension * extension)42 void PublicSessionMediaAccessHandler::HandleRequest(
43     content::WebContents* web_contents,
44     const content::MediaStreamRequest& request,
45     content::MediaResponseCallback callback,
46     const extensions::Extension* extension) {
47   // This class handles requests for Public Sessions only, outside of them just
48   // pass the request through to the original class.
49   if (!profiles::ArePublicSessionRestrictionsEnabled() ||
50       !extension->is_platform_app()) {
51     return extension_media_access_handler_.HandleRequest(
52         web_contents, request, std::move(callback), extension);
53   }
54 
55   // This Unretained is safe because the lifetime of this object is until
56   // process exit (living inside a base::Singleton object).
57   auto prompt_resolved_callback = base::AdaptCallbackForRepeating(
58       base::BindOnce(&PublicSessionMediaAccessHandler::ChainHandleRequest,
59                      base::Unretained(this), web_contents, request,
60                      std::move(callback), base::RetainedRef(extension)));
61 
62   extensions::PermissionIDSet requested_permissions;
63   if (request.audio_type == blink::mojom::MediaStreamType::DEVICE_AUDIO_CAPTURE)
64     requested_permissions.insert(extensions::APIPermission::kAudioCapture);
65   if (request.video_type == blink::mojom::MediaStreamType::DEVICE_VIDEO_CAPTURE)
66     requested_permissions.insert(extensions::APIPermission::kVideoCapture);
67 
68   extensions::permission_helper::HandlePermissionRequest(
69       *extension, requested_permissions, web_contents, prompt_resolved_callback,
70       extensions::permission_helper::PromptFactory());
71 }
72 
ChainHandleRequest(content::WebContents * web_contents,const content::MediaStreamRequest & request,content::MediaResponseCallback callback,const extensions::Extension * extension,const extensions::PermissionIDSet & allowed_permissions)73 void PublicSessionMediaAccessHandler::ChainHandleRequest(
74     content::WebContents* web_contents,
75     const content::MediaStreamRequest& request,
76     content::MediaResponseCallback callback,
77     const extensions::Extension* extension,
78     const extensions::PermissionIDSet& allowed_permissions) {
79   content::MediaStreamRequest request_copy(request);
80 
81   // If the user denies audio or video capture, here it gets filtered out from
82   // the request before being passed on to the actual implementation.
83   if (!allowed_permissions.ContainsID(extensions::APIPermission::kAudioCapture))
84     request_copy.audio_type = blink::mojom::MediaStreamType::NO_SERVICE;
85   if (!allowed_permissions.ContainsID(extensions::APIPermission::kVideoCapture))
86     request_copy.video_type = blink::mojom::MediaStreamType::NO_SERVICE;
87 
88   // Pass the request through to the original class.
89   extension_media_access_handler_.HandleRequest(web_contents, request_copy,
90                                                 std::move(callback), extension);
91 }
92