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

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

Issue 2532323003: Public Sessions - prompt the user for audioCapture/videoCapture requests (Closed)
Patch Set: Addressed comments #1 Created 4 years 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
(Empty)
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 <utility>
8
9 #include "base/bind.h"
10 #include "base/bind_helpers.h"
11 #include "base/memory/ptr_util.h"
12 #include "chromeos/login/login_state.h"
13 #include "content/public/browser/web_contents.h"
14 #include "extensions/common/extension.h"
15 #include "extensions/common/permissions/manifest_permission_set.h"
16 #include "extensions/common/permissions/permission_set.h"
17 #include "extensions/common/url_pattern_set.h"
18
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() {}
30
31 PublicSessionMediaAccessHandler::~PublicSessionMediaAccessHandler() {}
32
33 bool PublicSessionMediaAccessHandler::SupportsStreamType(
34 const content::MediaStreamType type,
35 const extensions::Extension* extension) {
36 return extension_media_access_handler_.SupportsStreamType(type, extension);
37 }
38
39 bool PublicSessionMediaAccessHandler::CheckMediaAccessPermission(
40 content::WebContents* web_contents,
41 const GURL& security_origin,
42 content::MediaStreamType type,
43 const extensions::Extension* extension) {
44 return extension_media_access_handler_.CheckMediaAccessPermission(
45 web_contents, security_origin, type, extension);
46 }
47
48 void PublicSessionMediaAccessHandler::HandleRequest(
49 content::WebContents* web_contents,
50 const content::MediaStreamRequest& request,
51 const content::MediaResponseCallback& callback,
52 const extensions::Extension* extension) {
53 // This class handles requests for Public Sessions only, outside of them just
54 // pass the request through to the original class.
55 if (!IsPublicSession() || !extension->is_platform_app()) {
56 return extension_media_access_handler_.HandleRequest(web_contents, request,
57 callback, extension);
58 }
59
60 bool needs_prompt = false;
61 extensions::APIPermissionSet new_apis;
62 const UserChoice& user_choice = user_choice_cache_[extension->id()];
63
64 if (user_choice.NeedsPrompting(request.audio_type)) {
65 new_apis.insert(extensions::APIPermission::kAudioCapture);
66 needs_prompt = true;
67 }
68 if (user_choice.NeedsPrompting(request.video_type)) {
69 new_apis.insert(extensions::APIPermission::kVideoCapture);
70 needs_prompt = true;
71 }
72
73 if (!needs_prompt)
74 return ChainHandleRequest(web_contents, request, callback, extension);
Ivan Šandrk 2016/12/05 13:10:51 Returning a void - a bad idea or clever removal of
75
76 auto permission_set = base::MakeUnique<extensions::PermissionSet>(
77 new_apis, extensions::ManifestPermissionSet(),
78 extensions::URLPatternSet(), extensions::URLPatternSet());
79
80 auto prompt = base::MakeUnique<ExtensionInstallPrompt>(web_contents);
81 // Raw copy used *only* for calling ShowDialog (to avoid the awkward
82 // situation where the same unique_ptr is used as this and is passed through
83 // inside a callback).
84 auto prompt_raw = prompt.get();
85
86 // "Dialog closed" callback owns the prompt, hence the prompt gets destroyed
87 // together with the callback. The callback is guaranteed to be destroyed
88 // even if it's not run.
89 prompt_raw->ShowDialog(
90 base::Bind(&PublicSessionMediaAccessHandler::ResolvePermissionPrompt,
91 base::Unretained(this), web_contents, request, callback,
92 extension, std::move(prompt)),
93 extension,
94 nullptr, // Uses the extension icon.
95 base::MakeUnique<ExtensionInstallPrompt::Prompt>(
96 ExtensionInstallPrompt::PERMISSIONS_PROMPT),
97 std::move(permission_set),
98 ExtensionInstallPrompt::GetDefaultShowDialogCallback());
99 }
100
101 void PublicSessionMediaAccessHandler::ChainHandleRequest(
102 content::WebContents* web_contents,
103 const content::MediaStreamRequest& request,
104 const content::MediaResponseCallback& callback,
105 const extensions::Extension* extension) {
106 DCHECK(IsPublicSession() && extension && extension->is_platform_app());
107 const UserChoice& user_choice = user_choice_cache_[extension->id()];
108 content::MediaStreamRequest request_copy(request);
109
110 if (!user_choice.IsAllowed(content::MEDIA_DEVICE_AUDIO_CAPTURE))
111 request_copy.audio_type = content::MEDIA_NO_SERVICE;
112 if (!user_choice.IsAllowed(content::MEDIA_DEVICE_VIDEO_CAPTURE))
113 request_copy.video_type = content::MEDIA_NO_SERVICE;
114
115 // Pass the request through to the original class.
116 extension_media_access_handler_.HandleRequest(web_contents, request_copy,
117 callback, extension);
118 }
119
120 void PublicSessionMediaAccessHandler::ResolvePermissionPrompt(
121 content::WebContents* web_contents,
122 const content::MediaStreamRequest& request,
123 const content::MediaResponseCallback& callback,
124 const extensions::Extension* extension,
125 const std::unique_ptr<ExtensionInstallPrompt>& prompt,
126 ExtensionInstallPrompt::Result prompt_result) {
127 bool allowed = prompt_result == ExtensionInstallPrompt::Result::ACCEPTED;
128 UserChoice& user_choice = user_choice_cache_[extension->id()];
129
130 if (user_choice.NeedsPrompting(request.audio_type))
131 user_choice.Set(content::MEDIA_DEVICE_AUDIO_CAPTURE, allowed);
132 if (user_choice.NeedsPrompting(request.video_type))
133 user_choice.Set(content::MEDIA_DEVICE_VIDEO_CAPTURE, allowed);
134
135 ChainHandleRequest(web_contents, request, callback, extension);
136 }
137
138 bool PublicSessionMediaAccessHandler::UserChoice::IsAllowed(
139 content::MediaStreamType type) const {
140 switch (type) {
141 case content::MEDIA_DEVICE_AUDIO_CAPTURE:
142 return !audio_prompted_ || audio_allowed_;
143 case content::MEDIA_DEVICE_VIDEO_CAPTURE:
144 return !video_prompted_ || video_allowed_;
145 default:
146 NOTREACHED();
147 return false;
148 }
149 }
150
151 bool PublicSessionMediaAccessHandler::UserChoice::NeedsPrompting(
152 content::MediaStreamType type) const {
153 switch (type) {
154 case content::MEDIA_DEVICE_AUDIO_CAPTURE:
155 return !audio_prompted_;
156 case content::MEDIA_DEVICE_VIDEO_CAPTURE:
157 return !video_prompted_;
158 default:
159 return false;
160 }
161 }
162
163 void PublicSessionMediaAccessHandler::UserChoice::Set(
164 content::MediaStreamType type, bool allowed) {
165 switch (type) {
166 case content::MEDIA_DEVICE_AUDIO_CAPTURE:
167 DCHECK(!audio_prompted_);
168 audio_prompted_ = true;
169 audio_allowed_ = allowed;
170 break;
171 case content::MEDIA_DEVICE_VIDEO_CAPTURE:
172 DCHECK(!video_prompted_);
173 video_prompted_ = true;
174 video_allowed_ = allowed;
175 break;
176 default:
177 NOTREACHED();
178 }
179 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698