Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(182)

Side by Side Diff: chrome/browser/media/public_session_media_access_handler.cc

Issue 2552203007: Public Sessions - prompt the user for pageCapture requests (Closed)
Patch Set: Nitfix Created 3 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Copyright 2016 The Chromium Authors. All rights reserved. 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 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "chrome/browser/media/public_session_media_access_handler.h" 5 #include "chrome/browser/media/public_session_media_access_handler.h"
6 6
7 #include <set>
7 #include <utility> 8 #include <utility>
8 9
9 #include "base/bind.h" 10 #include "base/bind.h"
10 #include "base/bind_helpers.h" 11 #include "base/bind_helpers.h"
11 #include "base/memory/ptr_util.h" 12 #include "base/memory/ptr_util.h"
13 #include "chrome/browser/chromeos/extensions/public_session_permission_helper.h"
14 #include "chrome/browser/profiles/profiles_state.h"
12 #include "chromeos/login/login_state.h" 15 #include "chromeos/login/login_state.h"
13 #include "content/public/browser/web_contents.h" 16 #include "content/public/browser/web_contents.h"
14 #include "extensions/common/extension.h" 17 #include "extensions/common/extension.h"
15 #include "extensions/common/permissions/manifest_permission_set.h" 18 #include "extensions/common/permissions/manifest_permission_set.h"
16 #include "extensions/common/permissions/permission_set.h" 19 #include "extensions/common/permissions/permission_set.h"
17 #include "extensions/common/url_pattern_set.h" 20 #include "extensions/common/url_pattern_set.h"
18 21
19 namespace {
20
21 // Returns true if we're in a Public Session.
22 bool IsPublicSession() {
23 return chromeos::LoginState::IsInitialized() &&
24 chromeos::LoginState::Get()->IsPublicSessionUser();
25 }
26
27 } // namespace
28
29 PublicSessionMediaAccessHandler::PublicSessionMediaAccessHandler() {} 22 PublicSessionMediaAccessHandler::PublicSessionMediaAccessHandler() {}
30 23
31 PublicSessionMediaAccessHandler::~PublicSessionMediaAccessHandler() {} 24 PublicSessionMediaAccessHandler::~PublicSessionMediaAccessHandler() {}
32 25
33 bool PublicSessionMediaAccessHandler::SupportsStreamType( 26 bool PublicSessionMediaAccessHandler::SupportsStreamType(
34 const content::MediaStreamType type, 27 const content::MediaStreamType type,
35 const extensions::Extension* extension) { 28 const extensions::Extension* extension) {
36 return extension_media_access_handler_.SupportsStreamType(type, extension); 29 return extension_media_access_handler_.SupportsStreamType(type, extension);
37 } 30 }
38 31
39 bool PublicSessionMediaAccessHandler::CheckMediaAccessPermission( 32 bool PublicSessionMediaAccessHandler::CheckMediaAccessPermission(
40 content::WebContents* web_contents, 33 content::WebContents* web_contents,
41 const GURL& security_origin, 34 const GURL& security_origin,
42 content::MediaStreamType type, 35 content::MediaStreamType type,
43 const extensions::Extension* extension) { 36 const extensions::Extension* extension) {
44 return extension_media_access_handler_.CheckMediaAccessPermission( 37 return extension_media_access_handler_.CheckMediaAccessPermission(
45 web_contents, security_origin, type, extension); 38 web_contents, security_origin, type, extension);
46 } 39 }
47 40
48 void PublicSessionMediaAccessHandler::HandleRequest( 41 void PublicSessionMediaAccessHandler::HandleRequest(
49 content::WebContents* web_contents, 42 content::WebContents* web_contents,
50 const content::MediaStreamRequest& request, 43 const content::MediaStreamRequest& request,
51 const content::MediaResponseCallback& callback, 44 const content::MediaResponseCallback& callback,
52 const extensions::Extension* extension) { 45 const extensions::Extension* extension) {
53 // This class handles requests for Public Sessions only, outside of them just 46 // This class handles requests for Public Sessions only, outside of them just
54 // pass the request through to the original class. 47 // pass the request through to the original class.
55 if (!IsPublicSession() || !extension->is_platform_app()) { 48 if (!profiles::IsPublicSession() || !extension->is_platform_app()) {
56 return extension_media_access_handler_.HandleRequest(web_contents, request, 49 return extension_media_access_handler_.HandleRequest(web_contents, request,
57 callback, extension); 50 callback, extension);
58 } 51 }
59 52
60 bool needs_prompt = false; 53 // This Unretained is safe because the lifetime of this object is until
61 extensions::APIPermissionSet new_apis; 54 // process exit (living inside a base::Singleton object).
62 UserChoice& user_choice = user_choice_cache_[extension->id()]; 55 auto prompt_resolved_callback = base::Bind(
56 &PublicSessionMediaAccessHandler::ChainHandleRequest,
57 base::Unretained(this), web_contents, request, callback, extension);
63 58
64 if (user_choice.NeedsPrompting(request.audio_type)) { 59 extensions::PermissionIDSet requested_permissions;
65 new_apis.insert(extensions::APIPermission::kAudioCapture); 60 if (request.audio_type == content::MEDIA_DEVICE_AUDIO_CAPTURE)
66 user_choice.SetPrompted(content::MEDIA_DEVICE_AUDIO_CAPTURE); 61 requested_permissions.insert(extensions::APIPermission::kAudioCapture);
67 needs_prompt = true; 62 if (request.video_type == content::MEDIA_DEVICE_VIDEO_CAPTURE)
68 } 63 requested_permissions.insert(extensions::APIPermission::kVideoCapture);
69 if (user_choice.NeedsPrompting(request.video_type)) {
70 new_apis.insert(extensions::APIPermission::kVideoCapture);
71 user_choice.SetPrompted(content::MEDIA_DEVICE_VIDEO_CAPTURE);
72 needs_prompt = true;
73 }
74 64
75 if (!needs_prompt) 65 extensions::permission_helper::HandlePermissionRequest(
76 return ChainHandleRequest(web_contents, request, callback, extension); 66 *extension, requested_permissions, web_contents, prompt_resolved_callback,
77 67 extensions::permission_helper::PromptFactory());
78 auto permission_set = base::MakeUnique<extensions::PermissionSet>(
79 new_apis, extensions::ManifestPermissionSet(),
80 extensions::URLPatternSet(), extensions::URLPatternSet());
81
82 auto prompt = base::MakeUnique<ExtensionInstallPrompt>(web_contents);
83
84 prompt->ShowDialog(
85 base::Bind(&PublicSessionMediaAccessHandler::ResolvePermissionPrompt,
86 base::Unretained(this), web_contents, request, callback,
87 extension),
88 extension,
89 nullptr, // Uses the extension icon.
90 base::MakeUnique<ExtensionInstallPrompt::Prompt>(
91 ExtensionInstallPrompt::PERMISSIONS_PROMPT),
92 std::move(permission_set),
93 ExtensionInstallPrompt::GetDefaultShowDialogCallback());
94
95 extension_install_prompt_map_[extension->id()] = std::move(prompt);
96 } 68 }
97 69
98 void PublicSessionMediaAccessHandler::ChainHandleRequest( 70 void PublicSessionMediaAccessHandler::ChainHandleRequest(
99 content::WebContents* web_contents, 71 content::WebContents* web_contents,
100 const content::MediaStreamRequest& request, 72 const content::MediaStreamRequest& request,
101 const content::MediaResponseCallback& callback, 73 const content::MediaResponseCallback& callback,
102 const extensions::Extension* extension) { 74 const extensions::Extension* extension,
103 DCHECK(IsPublicSession() && extension && extension->is_platform_app()); 75 const extensions::PermissionIDSet& allowed_permissions) {
104 const UserChoice& user_choice = user_choice_cache_[extension->id()];
105 content::MediaStreamRequest request_copy(request); 76 content::MediaStreamRequest request_copy(request);
106 77
107 // If the user denies audio or video capture, here it gets filtered out from 78 // If the user denies audio or video capture, here it gets filtered out from
108 // the request before being passed on to the actual implementation. 79 // the request before being passed on to the actual implementation.
109 if (!user_choice.IsAllowed(content::MEDIA_DEVICE_AUDIO_CAPTURE)) 80 if (!allowed_permissions.ContainsID(extensions::APIPermission::kAudioCapture))
110 request_copy.audio_type = content::MEDIA_NO_SERVICE; 81 request_copy.audio_type = content::MEDIA_NO_SERVICE;
111 if (!user_choice.IsAllowed(content::MEDIA_DEVICE_VIDEO_CAPTURE)) 82 if (!allowed_permissions.ContainsID(extensions::APIPermission::kVideoCapture))
112 request_copy.video_type = content::MEDIA_NO_SERVICE; 83 request_copy.video_type = content::MEDIA_NO_SERVICE;
113 84
114 // Pass the request through to the original class. 85 // Pass the request through to the original class.
115 extension_media_access_handler_.HandleRequest(web_contents, request_copy, 86 extension_media_access_handler_.HandleRequest(web_contents, request_copy,
116 callback, extension); 87 callback, extension);
117 } 88 }
118
119 void PublicSessionMediaAccessHandler::ResolvePermissionPrompt(
120 content::WebContents* web_contents,
121 const content::MediaStreamRequest& request,
122 const content::MediaResponseCallback& callback,
123 const extensions::Extension* extension,
124 ExtensionInstallPrompt::Result prompt_result) {
125 // Dispose of the prompt as it's not needed anymore.
126 extension_install_prompt_map_.erase(extension->id());
127
128 bool allowed = prompt_result == ExtensionInstallPrompt::Result::ACCEPTED;
129 UserChoice& user_choice = user_choice_cache_[extension->id()];
130
131 if (request.audio_type == content::MEDIA_DEVICE_AUDIO_CAPTURE)
132 user_choice.Set(content::MEDIA_DEVICE_AUDIO_CAPTURE, allowed);
133 if (request.video_type == content::MEDIA_DEVICE_VIDEO_CAPTURE)
134 user_choice.Set(content::MEDIA_DEVICE_VIDEO_CAPTURE, allowed);
135
136 ChainHandleRequest(web_contents, request, callback, extension);
137 }
138
139 bool PublicSessionMediaAccessHandler::UserChoice::IsAllowed(
140 content::MediaStreamType type) const {
141 switch (type) {
142 case content::MEDIA_DEVICE_AUDIO_CAPTURE:
143 return !audio_prompted_ || audio_allowed_;
144 case content::MEDIA_DEVICE_VIDEO_CAPTURE:
145 return !video_prompted_ || video_allowed_;
146 default:
147 NOTREACHED();
148 return false;
149 }
150 }
151
152 bool PublicSessionMediaAccessHandler::UserChoice::NeedsPrompting(
153 content::MediaStreamType type) const {
154 switch (type) {
155 case content::MEDIA_DEVICE_AUDIO_CAPTURE:
156 return !audio_prompted_;
157 case content::MEDIA_DEVICE_VIDEO_CAPTURE:
158 return !video_prompted_;
159 default:
160 return false;
161 }
162 }
163
164 void PublicSessionMediaAccessHandler::UserChoice::Set(
165 content::MediaStreamType type,
166 bool allowed) {
167 switch (type) {
168 case content::MEDIA_DEVICE_AUDIO_CAPTURE:
169 audio_allowed_ = allowed;
170 break;
171 case content::MEDIA_DEVICE_VIDEO_CAPTURE:
172 video_allowed_ = allowed;
173 break;
174 default:
175 NOTREACHED();
176 }
177 }
178
179 void PublicSessionMediaAccessHandler::UserChoice::SetPrompted(
180 content::MediaStreamType type) {
181 switch (type) {
182 case content::MEDIA_DEVICE_AUDIO_CAPTURE:
183 audio_prompted_ = true;
184 break;
185 case content::MEDIA_DEVICE_VIDEO_CAPTURE:
186 video_prompted_ = true;
187 break;
188 default:
189 NOTREACHED();
190 }
191 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698