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

Side by Side Diff: chrome/browser/permissions/permission_manager.cc

Issue 1260193009: renderer: implement multiple permission requesting (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@permissions-request-multiple
Patch Set: Merge patches Created 5 years, 4 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 2015 The Chromium Authors. All rights reserved. 1 // Copyright 2015 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/permissions/permission_manager.h" 5 #include "chrome/browser/permissions/permission_manager.h"
6 6
7 #include "base/callback.h" 7 #include "base/callback.h"
8 #include "chrome/browser/permissions/permission_context.h" 8 #include "chrome/browser/permissions/permission_context.h"
9 #include "chrome/browser/permissions/permission_context_base.h" 9 #include "chrome/browser/permissions/permission_context_base.h"
10 #include "chrome/browser/permissions/permission_request_id.h" 10 #include "chrome/browser/permissions/permission_request_id.h"
(...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after
71 // Helper method that wraps a callback a void(PermissionStatus) 71 // Helper method that wraps a callback a void(PermissionStatus)
72 // callback into a void(ContentSetting) callback. 72 // callback into a void(ContentSetting) callback.
73 void PermissionStatusCallbackWrapper( 73 void PermissionStatusCallbackWrapper(
74 const base::Callback<void(PermissionStatus)>& callback, 74 const base::Callback<void(PermissionStatus)>& callback,
75 ContentSetting content_setting) { 75 ContentSetting content_setting) {
76 callback.Run(ContentSettingToPermissionStatus(content_setting)); 76 callback.Run(ContentSettingToPermissionStatus(content_setting));
77 } 77 }
78 78
79 } // anonymous namespace 79 } // anonymous namespace
80 80
81 struct PermissionManager::PendingResponse {
Lalit Maganti (personal) 2015/08/03 23:10:26 Move to header and keep implementation here.
82 bool responded;
83 PermissionType type;
84 PermissionStatus status;
85
86 PendingResponse(bool responded, PermissionType type, PermissionStatus status)
87 : responded(responded), type(type), status(status) {
88 }
89 };
90
91 struct PermissionManager::PendingResponses {
Lalit Maganti (personal) 2015/08/03 23:10:26 Ditto.
92 GURL requesting_origin;
93 size_t count;
Lalit Maganti (personal) 2015/08/03 23:10:26 Make this immutable and another field.
94 std::vector<PendingResponse> responses;
95 base::Callback<void(const StatusVector&)> callback;
96 };
97
81 struct PermissionManager::Subscription { 98 struct PermissionManager::Subscription {
82 PermissionType permission; 99 PermissionType permission;
83 GURL requesting_origin; 100 GURL requesting_origin;
84 GURL embedding_origin; 101 GURL embedding_origin;
85 base::Callback<void(PermissionStatus)> callback; 102 base::Callback<void(PermissionStatus)> callback;
86 ContentSetting current_value; 103 ContentSetting current_value;
87 }; 104 };
88 105
89 PermissionManager::PermissionManager(Profile* profile) 106 PermissionManager::PermissionManager(Profile* profile)
90 : profile_(profile) { 107 : profile_(profile),
108 weak_ptr_factory_(this) {
91 } 109 }
92 110
93 PermissionManager::~PermissionManager() { 111 PermissionManager::~PermissionManager() {
94 if (!subscriptions_.IsEmpty()) 112 if (!subscriptions_.IsEmpty())
95 profile_->GetHostContentSettingsMap()->RemoveObserver(this); 113 profile_->GetHostContentSettingsMap()->RemoveObserver(this);
96 } 114 }
97 115
98 void PermissionManager::RequestPermission( 116 void PermissionManager::RequestPermission(
99 PermissionType permission, 117 PermissionType permission,
100 content::RenderFrameHost* render_frame_host, 118 content::RenderFrameHost* render_frame_host,
(...skipping 14 matching lines...) Expand all
115 request_id, 133 request_id,
116 requesting_origin); 134 requesting_origin);
117 135
118 context->RequestPermission( 136 context->RequestPermission(
119 content::WebContents::FromRenderFrameHost(render_frame_host), 137 content::WebContents::FromRenderFrameHost(render_frame_host),
120 request, requesting_origin, user_gesture, 138 request, requesting_origin, user_gesture,
121 base::Bind(&PermissionStatusCallbackWrapper, 139 base::Bind(&PermissionStatusCallbackWrapper,
122 callback)); 140 callback));
123 } 141 }
124 142
143 void PermissionManager::RequestPermissions(
144 const std::vector<PermissionType>& permissions,
145 content::RenderFrameHost* render_frame_host,
146 int request_id,
147 const GURL& requesting_origin,
148 bool user_gesture,
149 const base::Callback<void(const StatusVector&)>& callback) {
150 int render_process_id = render_frame_host->GetProcess()->GetID();
151 int render_frame_id = render_frame_host->GetRoutingID();
152 const PermissionRequestID request(render_process_id,
153 render_frame_id,
154 request_id,
155 requesting_origin);
156
157 // Pass complete control of the scoped pointer to the map.
158 // Locally we will use the raw pointer and the response will be removed from
159 // the map once all the responses return.
160 scoped_ptr<PendingResponses> scoped_response(new PendingResponses());
161 PendingResponses *pending_responses = scoped_response.get();
Lalit Maganti (personal) 2015/08/03 23:10:26 Move *
162 pending_batch_responses_.add(request_id, scoped_response.Pass());
163
164 pending_responses->requesting_origin = requesting_origin;
165 pending_responses->count = permissions.size();
166 pending_responses->callback = callback;
167
168 for (size_t i = 0; i < permissions.size(); ++i) {
169 pending_responses->responses.emplace_back(
170 false,
171 permissions[i],
172 content::PERMISSION_STATUS_DENIED);
173
174 PermissionContextBase* context =
175 PermissionContext::Get(profile_, permissions[i]);
176 if (!context) {
177 OnRequestsResponse(callback, request, pending_responses, i,
178 CONTENT_SETTING_BLOCK);
179 continue;
180 }
181 context->RequestPermission(
182 content::WebContents::FromRenderFrameHost(render_frame_host),
183 request, requesting_origin, user_gesture,
184 base::Bind(&PermissionManager::OnRequestsResponse,
185 weak_ptr_factory_.GetWeakPtr(),
186 callback,
187 request,
188 pending_responses,
189 i));
190 }
191 }
192
193 void PermissionManager::OnRequestsResponse(
194 const base::Callback<void(const StatusVector&)>& callback,
195 const PermissionRequestID request,
196 PendingResponses* pending_responses,
197 int index,
198 ContentSetting content_setting) {
199 PendingResponse& response = pending_responses->responses[index];
200 response.status = ContentSettingToPermissionStatus(content_setting);
201
202 if (--pending_responses->count == 0) {
203 std::vector<PermissionStatus> status;
204 for (auto response : pending_responses->responses) {
205 status.push_back(response.status);
206 }
207 callback.Run(status);
Lalit Maganti (personal) 2015/08/03 23:10:26 Move this after next line
208
209 pending_batch_responses_.erase(request.request_id());
210 }
211 }
212
125 void PermissionManager::CancelPermissionRequest( 213 void PermissionManager::CancelPermissionRequest(
126 PermissionType permission, 214 PermissionType permission,
127 content::RenderFrameHost* render_frame_host, 215 content::RenderFrameHost* render_frame_host,
128 int request_id, 216 int request_id,
129 const GURL& requesting_origin) { 217 const GURL& requesting_origin) {
130 PermissionContextBase* context = PermissionContext::Get(profile_, permission); 218 PermissionContextBase* context = PermissionContext::Get(profile_, permission);
131 if (!context) 219 if (!context)
132 return; 220 return;
133 221
134 int render_process_id = render_frame_host->GetProcess()->GetID(); 222 int render_process_id = render_frame_host->GetProcess()->GetID();
135 int render_frame_id = render_frame_host->GetRoutingID(); 223 int render_frame_id = render_frame_host->GetRoutingID();
136 const PermissionRequestID request(render_process_id, 224 const PermissionRequestID request(render_process_id,
137 render_frame_id, 225 render_frame_id,
138 request_id, 226 request_id,
139 requesting_origin); 227 requesting_origin);
140 228
141 context->CancelPermissionRequest( 229 context->CancelPermissionRequest(
142 content::WebContents::FromRenderFrameHost(render_frame_host), request); 230 content::WebContents::FromRenderFrameHost(render_frame_host), request);
143 } 231 }
144 232
233 void PermissionManager::CancelPermissionsRequest(
234 content::RenderFrameHost* render_frame_host,
235 int request_id) {
236 PendingResponses* pending_responses =
237 pending_batch_responses_.get(request_id);
238
239 int render_process_id = render_frame_host->GetProcess()->GetID();
240 int render_frame_id = render_frame_host->GetRoutingID();
241 const PermissionRequestID request(render_process_id,
242 render_frame_id,
243 request_id,
244 pending_responses->requesting_origin);
245
246 for (size_t i = 0; i < pending_responses->count; ++i) {
Lalit Maganti (personal) 2015/08/03 23:10:26 This is totally wrong - we need to store actual an
247 PermissionContextBase* context =
248 PermissionContext::Get(profile_, pending_responses->responses[i].type);
249 if (!context) continue;
250
251 context->CancelPermissionRequest(
252 content::WebContents::FromRenderFrameHost(render_frame_host), request);
253 }
254 pending_batch_responses_.clear();
255 }
256
145 void PermissionManager::ResetPermission(PermissionType permission, 257 void PermissionManager::ResetPermission(PermissionType permission,
146 const GURL& requesting_origin, 258 const GURL& requesting_origin,
147 const GURL& embedding_origin) { 259 const GURL& embedding_origin) {
148 PermissionContextBase* context = PermissionContext::Get(profile_, permission); 260 PermissionContextBase* context = PermissionContext::Get(profile_, permission);
149 if (!context) 261 if (!context)
150 return; 262 return;
151 263
152 context->ResetPermission(requesting_origin.GetOrigin(), 264 context->ResetPermission(requesting_origin.GetOrigin(),
153 embedding_origin.GetOrigin()); 265 embedding_origin.GetOrigin());
154 } 266 }
(...skipping 82 matching lines...) Expand 10 before | Expand all | Expand 10 after
237 // Add the callback to |callbacks| which will be run after the loop to 349 // Add the callback to |callbacks| which will be run after the loop to
238 // prevent re-entrance issues. 350 // prevent re-entrance issues.
239 callbacks.push_back( 351 callbacks.push_back(
240 base::Bind(subscription->callback, 352 base::Bind(subscription->callback,
241 ContentSettingToPermissionStatus(new_value))); 353 ContentSettingToPermissionStatus(new_value)));
242 } 354 }
243 355
244 for (const auto& callback : callbacks) 356 for (const auto& callback : callbacks)
245 callback.Run(); 357 callback.Run();
246 } 358 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698