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

Side by Side Diff: chrome/browser/chromeos/extensions/public_session_permission_helper.cc

Issue 2697833004: Revert of Public Sessions - prompt the user for pageCapture requests (Closed)
Patch Set: 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
(Empty)
1 // Copyright 2017 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/chromeos/extensions/public_session_permission_helper.h"
6
7 #include <algorithm>
8 #include <map>
9 #include <memory>
10 #include <utility>
11 #include <vector>
12
13 #include "base/bind.h"
14 #include "base/bind_helpers.h"
15 #include "base/lazy_instance.h"
16 #include "base/macros.h"
17 #include "base/memory/ptr_util.h"
18 #include "chrome/browser/extensions/extension_install_prompt.h"
19 #include "content/public/browser/browser_thread.h"
20 #include "content/public/browser/web_contents.h"
21 #include "extensions/common/extension.h"
22 #include "extensions/common/extension_id.h"
23 #include "extensions/common/permissions/manifest_permission_set.h"
24 #include "extensions/common/permissions/permission_set.h"
25 #include "extensions/common/url_pattern_set.h"
26
27 namespace extensions {
28 namespace permission_helper {
29
30 namespace {
31
32 std::unique_ptr<ExtensionInstallPrompt> CreateExtensionInstallPrompt(
33 content::WebContents* web_contents) {
34 return base::MakeUnique<ExtensionInstallPrompt>(web_contents);
35 }
36
37 // This class is the internal implementation of HandlePermissionRequest(). It
38 // contains the actual prompt showing and resolving logic, and it caches the
39 // user choices.
40 class PublicSessionPermissionHelper {
41 public:
42 PublicSessionPermissionHelper();
43 PublicSessionPermissionHelper(PublicSessionPermissionHelper&& other);
44 ~PublicSessionPermissionHelper();
45
46 void HandlePermissionRequestImpl(const Extension& extension,
47 const PermissionIDSet& requested_permissions,
48 content::WebContents* web_contents,
49 const RequestResolvedCallback& callback,
50 const PromptFactory& prompt_factory);
51
52 private:
53 void ResolvePermissionPrompt(const ExtensionInstallPrompt* prompt,
54 const PermissionIDSet& unprompted_permissions,
55 ExtensionInstallPrompt::Result prompt_result);
56
57 PermissionIDSet FilterAllowedPermissions(const PermissionIDSet& permissions);
58
59 struct RequestCallback {
60 RequestCallback(const RequestResolvedCallback& callback,
61 const PermissionIDSet& permission_list);
62 RequestCallback(const RequestCallback& other);
63 ~RequestCallback();
64 RequestResolvedCallback callback;
65 PermissionIDSet permission_list;
66 };
67 using RequestCallbackList = std::vector<RequestCallback>;
68
69 std::set<std::unique_ptr<ExtensionInstallPrompt>> prompts_;
70 PermissionIDSet prompted_permission_set_;
71 PermissionIDSet allowed_permission_set_;
72 PermissionIDSet denied_permission_set_;
73 RequestCallbackList callbacks_;
74
75 DISALLOW_COPY_AND_ASSIGN(PublicSessionPermissionHelper);
76 };
77
78 PublicSessionPermissionHelper::PublicSessionPermissionHelper() {}
79
80 PublicSessionPermissionHelper::PublicSessionPermissionHelper(
81 PublicSessionPermissionHelper&& other) = default;
82
83 PublicSessionPermissionHelper::~PublicSessionPermissionHelper() {}
84
85 void PublicSessionPermissionHelper::HandlePermissionRequestImpl(
86 const Extension& extension,
87 const PermissionIDSet& requested_permissions,
88 content::WebContents* web_contents,
89 const RequestResolvedCallback& callback,
90 const PromptFactory& prompt_factory) {
91 CHECK(web_contents);
92
93 PermissionIDSet unresolved_permissions = PermissionIDSet::Difference(
94 requested_permissions, allowed_permission_set_);
95 unresolved_permissions = PermissionIDSet::Difference(
96 unresolved_permissions, denied_permission_set_);
97 if (unresolved_permissions.empty()) {
98 // All requested permissions are already resolved.
99 callback.Run(FilterAllowedPermissions(requested_permissions));
100 return;
101 }
102
103 // Since not all permissions are resolved yet, queue the callback to be called
104 // when all of them are resolved.
105 callbacks_.push_back(RequestCallback(callback, requested_permissions));
106
107 PermissionIDSet unprompted_permissions = PermissionIDSet::Difference(
108 unresolved_permissions, prompted_permission_set_);
109 if (unprompted_permissions.empty()) {
110 // Some permissions aren't resolved yet, but they are currently being
111 // prompted for, so no need to show a prompt.
112 return;
113 }
114
115 // Some permissions need prompting, setup the prompt and show it.
116 APIPermissionSet new_apis;
117 for (const auto& permission : unprompted_permissions) {
118 prompted_permission_set_.insert(permission.id());
119 new_apis.insert(permission.id());
120 }
121 auto permission_set = base::MakeUnique<PermissionSet>(
122 new_apis, ManifestPermissionSet(), URLPatternSet(), URLPatternSet());
123 auto prompt = prompt_factory.Run(web_contents);
124 // This Unretained is safe because the lifetime of this object is until
125 // process exit.
126 prompt->ShowDialog(
127 base::Bind(&PublicSessionPermissionHelper::ResolvePermissionPrompt,
128 base::Unretained(this), prompt.get(),
129 std::move(unprompted_permissions)),
130 &extension,
131 nullptr, // Use the extension icon.
132 base::MakeUnique<ExtensionInstallPrompt::Prompt>(
133 ExtensionInstallPrompt::PERMISSIONS_PROMPT),
134 std::move(permission_set),
135 ExtensionInstallPrompt::GetDefaultShowDialogCallback());
136 prompts_.insert(std::move(prompt));
137 }
138
139 void PublicSessionPermissionHelper::ResolvePermissionPrompt(
140 const ExtensionInstallPrompt* prompt,
141 const PermissionIDSet& unprompted_permissions,
142 ExtensionInstallPrompt::Result prompt_result) {
143 PermissionIDSet& add_to_set =
144 prompt_result == ExtensionInstallPrompt::Result::ACCEPTED ?
145 allowed_permission_set_ : denied_permission_set_;
146 for (const auto& permission : unprompted_permissions) {
147 prompted_permission_set_.erase(permission.id());
148 add_to_set.insert(permission.id());
149 }
150
151 // Here a list of callbacks to be invoked is created first from callbacks_,
152 // then those callbacks are invoked later because a callback can change
153 // callbacks_ while we're traversing them.
154 RequestCallbackList callbacks_to_invoke;
155 for (auto callback = callbacks_.begin(); callback != callbacks_.end(); ) {
156 if (prompted_permission_set_.ContainsAnyID(callback->permission_list)) {
157 // The request is still waiting on other permissions to be resolved - wait
158 // until all of them are resolved before calling the callback.
159 callback++;
160 continue;
161 }
162 callbacks_to_invoke.push_back(std::move(*callback));
163 callback = callbacks_.erase(callback);
164 }
165 for (auto callback = callbacks_to_invoke.begin();
166 callback != callbacks_to_invoke.end(); callback++) {
167 callback->callback.Run(FilterAllowedPermissions(callback->permission_list));
168 }
169
170 // Dispose of the prompt as it's not needed anymore.
171 auto iter = std::find_if(
172 prompts_.begin(), prompts_.end(),
173 [prompt](const std::unique_ptr<ExtensionInstallPrompt>& check) {
174 return check.get() == prompt;
175 });
176 DCHECK(iter != prompts_.end());
177 prompts_.erase(iter);
178 }
179
180 PermissionIDSet PublicSessionPermissionHelper::FilterAllowedPermissions(
181 const PermissionIDSet& permissions) {
182 PermissionIDSet allowed_permissions;
183 for (auto iter = permissions.begin(); iter != permissions.end(); iter++) {
184 if (allowed_permission_set_.ContainsID(*iter)) {
185 allowed_permissions.insert(iter->id());
186 }
187 }
188 return allowed_permissions;
189 }
190
191 PublicSessionPermissionHelper::RequestCallback::RequestCallback(
192 const RequestResolvedCallback& callback,
193 const PermissionIDSet& permission_list)
194 : callback(callback), permission_list(permission_list) {}
195
196 PublicSessionPermissionHelper::RequestCallback::RequestCallback(
197 const RequestCallback& other) = default;
198
199 PublicSessionPermissionHelper::RequestCallback::~RequestCallback() {}
200
201 base::LazyInstance<std::map<ExtensionId, PublicSessionPermissionHelper>>::Leaky
202 g_helpers = LAZY_INSTANCE_INITIALIZER;
203
204 } // namespace
205
206 void HandlePermissionRequest(const Extension& extension,
207 const PermissionIDSet& requested_permissions,
208 content::WebContents* web_contents,
209 const RequestResolvedCallback& callback,
210 const PromptFactory& prompt_factory) {
211 DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
212 const PromptFactory& factory = prompt_factory.is_null()
213 ? base::Bind(&CreateExtensionInstallPrompt)
214 : prompt_factory;
215 return g_helpers.Get()[extension.id()].HandlePermissionRequestImpl(
216 extension, requested_permissions, web_contents, callback, factory);
217 }
218
219 void ResetPermissionsForTesting() {
220 g_helpers = LAZY_INSTANCE_INITIALIZER;
221 }
222
223 } // namespace permission_helper
224 } // namespace extensions
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698