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

Side by Side Diff: content/browser/browser_plugin/browser_plugin_guest.cc

Issue 69913002: Add UMA for <webview> APIs: a. ClearData, b. when Permission request is allowed. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Refine by permission granularity. Created 7 years, 1 month 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 (c) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 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 "content/browser/browser_plugin/browser_plugin_guest.h" 5 #include "content/browser/browser_plugin/browser_plugin_guest.h"
6 6
7 #include <algorithm> 7 #include <algorithm>
8 8
9 #include "base/message_loop/message_loop.h" 9 #include "base/message_loop/message_loop.h"
10 #include "base/strings/string_util.h" 10 #include "base/strings/string_util.h"
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after
45 #include "net/url_request/url_request.h" 45 #include "net/url_request/url_request.h"
46 #include "third_party/WebKit/public/web/WebCursorInfo.h" 46 #include "third_party/WebKit/public/web/WebCursorInfo.h"
47 #include "ui/events/keycodes/keyboard_codes.h" 47 #include "ui/events/keycodes/keyboard_codes.h"
48 #include "ui/surface/transport_dib.h" 48 #include "ui/surface/transport_dib.h"
49 #include "webkit/common/resource_type.h" 49 #include "webkit/common/resource_type.h"
50 50
51 #if defined(OS_MACOSX) 51 #if defined(OS_MACOSX)
52 #include "content/browser/browser_plugin/browser_plugin_popup_menu_helper_mac.h" 52 #include "content/browser/browser_plugin/browser_plugin_popup_menu_helper_mac.h"
53 #endif 53 #endif
54 54
55 namespace {
56 enum UmaType {
57 UMA_TYPE_DOWNLOAD,
58 UMA_TYPE_GEOLOCATION,
59 UMA_TYPE_MEDIA,
60 UMA_TYPE_POINTER_LOCK,
61 UMA_TYPE_NEW_WINDOW,
62 UMA_TYPE_JAVASCRIPT_DIALOG,
63 };
64 } // namespace
65
55 namespace content { 66 namespace content {
56 67
57 // static 68 // static
58 BrowserPluginHostFactory* BrowserPluginGuest::factory_ = NULL; 69 BrowserPluginHostFactory* BrowserPluginGuest::factory_ = NULL;
59 70
60 // Parent class for the various types of permission requests, each of which 71 // Parent class for the various types of permission requests, each of which
61 // should be able to handle the response to their permission request. 72 // should be able to handle the response to their permission request.
62 class BrowserPluginGuest::PermissionRequest : 73 class BrowserPluginGuest::PermissionRequest :
63 public base::RefCounted<BrowserPluginGuest::PermissionRequest> { 74 public base::RefCounted<BrowserPluginGuest::PermissionRequest> {
64 public: 75 public:
65 virtual void Respond(bool should_allow, const std::string& user_input) = 0; 76 virtual void Respond(bool should_allow,
77 const std::string& user_input,
78 bool user_initiated) = 0;
66 virtual bool AllowedByDefault() const { 79 virtual bool AllowedByDefault() const {
67 return false; 80 return false;
68 } 81 }
82
69 protected: 83 protected:
70 PermissionRequest() { 84 PermissionRequest() {
71 RecordAction(UserMetricsAction("BrowserPlugin.Guest.PermissionRequest")); 85 RecordAction(UserMetricsAction("BrowserPlugin.Guest.PermissionRequest"));
72 } 86 }
73 virtual ~PermissionRequest() {} 87 virtual ~PermissionRequest() {}
88
89 // Only record user initiated (i.e. non-default) actions.
90 void MaybeRecordUserMetrics(UmaType uma_type,
91 bool allow,
92 bool user_initiated) const {
93 if (!user_initiated)
94 return;
95
96 if (allow) {
97 // Note that |allow| == true means the embedder explicitly allowed the
98 // request. For some requests they might still fail. An example of such
99 // scenario would be: an embedder allows geolocation request but doesn't
100 // have geolocation access on its own.
101 switch (uma_type) {
102 case UMA_TYPE_DOWNLOAD:
103 RecordAction(UserMetricsAction(
104 "BrowserPlugin.Guest.PermissionAllow.Download"));
Fady Samuel 2013/11/13 15:54:05 All these strings are really similar. Can't you si
lazyboy 2013/11/13 17:35:33 As discussed offline and after talking to sadrul@,
105 break;
106 case UMA_TYPE_GEOLOCATION:
107 RecordAction(UserMetricsAction(
108 "BrowserPlugin.Guest.PermissionAllow.Geolocation"));
109 break;
110 case UMA_TYPE_MEDIA:
111 RecordAction(UserMetricsAction(
112 "BrowserPlugin.Guest.PermissionAllow.Media"));
113 break;
114 case UMA_TYPE_POINTER_LOCK:
115 RecordAction(UserMetricsAction(
116 "BrowserPlugin.Guest.PermissionAllow.PointerLock"));
117 break;
118 case UMA_TYPE_NEW_WINDOW:
119 RecordAction(UserMetricsAction(
120 "BrowserPlugin.Guest.PermissionAllow.NewWindow"));
121 break;
122 case UMA_TYPE_JAVASCRIPT_DIALOG:
123 RecordAction(
124 UserMetricsAction(
125 "BrowserPlugin.Guest.PermissionAllow.JavaScriptDialog"));
126 break;
127 }
128 } else {
129 switch (uma_type) {
130 case UMA_TYPE_DOWNLOAD:
131 RecordAction(UserMetricsAction(
132 "BrowserPlugin.Guest.PermissionDeny.Download"));
133 break;
134 case UMA_TYPE_GEOLOCATION:
135 RecordAction(UserMetricsAction(
136 "BrowserPlugin.Guest.PermissionDeny.Geolocation"));
137 break;
138 case UMA_TYPE_MEDIA:
139 RecordAction(UserMetricsAction(
140 "BrowserPlugin.Guest.PermissionDeny.Media"));
141 break;
142 case UMA_TYPE_POINTER_LOCK:
143 RecordAction(UserMetricsAction(
144 "BrowserPlugin.Guest.PermissionDeny.PointerLock"));
145 break;
146 case UMA_TYPE_NEW_WINDOW:
147 RecordAction(UserMetricsAction(
148 "BrowserPlugin.Guest.PermissionDeny.NewWindow"));
149 break;
150 case UMA_TYPE_JAVASCRIPT_DIALOG:
151 RecordAction(
152 UserMetricsAction(
153 "BrowserPlugin.Guest.PermissionDeny.JavaScriptDialog"));
154 break;
155 }
156 }
157 }
158
74 // Friend RefCounted so that the dtor can be non-public. 159 // Friend RefCounted so that the dtor can be non-public.
75 friend class base::RefCounted<BrowserPluginGuest::PermissionRequest>; 160 friend class base::RefCounted<BrowserPluginGuest::PermissionRequest>;
76 }; 161 };
77 162
78 class BrowserPluginGuest::DownloadRequest : public PermissionRequest { 163 class BrowserPluginGuest::DownloadRequest : public PermissionRequest {
79 public: 164 public:
80 explicit DownloadRequest(base::Callback<void(bool)> callback) 165 explicit DownloadRequest(base::Callback<void(bool)> callback)
81 : callback_(callback) { 166 : callback_(callback) {
82 RecordAction( 167 RecordAction(
83 UserMetricsAction("BrowserPlugin.Guest.PermissionRequest.Download")); 168 UserMetricsAction("BrowserPlugin.Guest.PermissionRequest.Download"));
84 } 169 }
85 virtual void Respond(bool should_allow, 170 virtual void Respond(bool should_allow,
86 const std::string& user_input) OVERRIDE { 171 const std::string& user_input,
172 bool user_initiated) OVERRIDE {
87 callback_.Run(should_allow); 173 callback_.Run(should_allow);
174 MaybeRecordUserMetrics(UMA_TYPE_DOWNLOAD, should_allow, user_initiated);
88 } 175 }
89 176
90 private: 177 private:
91 virtual ~DownloadRequest() {} 178 virtual ~DownloadRequest() {}
92 base::Callback<void(bool)> callback_; 179 base::Callback<void(bool)> callback_;
93 }; 180 };
94 181
95 class BrowserPluginGuest::GeolocationRequest : public PermissionRequest { 182 class BrowserPluginGuest::GeolocationRequest : public PermissionRequest {
96 public: 183 public:
97 GeolocationRequest(GeolocationCallback callback, 184 GeolocationRequest(GeolocationCallback callback,
98 int bridge_id, 185 int bridge_id,
99 base::WeakPtrFactory<BrowserPluginGuest>* weak_ptr_factory) 186 base::WeakPtrFactory<BrowserPluginGuest>* weak_ptr_factory)
100 : callback_(callback), 187 : callback_(callback),
101 bridge_id_(bridge_id), 188 bridge_id_(bridge_id),
102 weak_ptr_factory_(weak_ptr_factory) { 189 weak_ptr_factory_(weak_ptr_factory) {
103 RecordAction( 190 RecordAction(
104 UserMetricsAction("BrowserPlugin.Guest.PermissionRequest.Geolocation")); 191 UserMetricsAction("BrowserPlugin.Guest.PermissionRequest.Geolocation"));
105 } 192 }
106 193
107 virtual void Respond(bool should_allow, 194 virtual void Respond(bool should_allow,
108 const std::string& user_input) OVERRIDE { 195 const std::string& user_input,
196 bool user_initiated) OVERRIDE {
109 base::WeakPtr<BrowserPluginGuest> guest(weak_ptr_factory_->GetWeakPtr()); 197 base::WeakPtr<BrowserPluginGuest> guest(weak_ptr_factory_->GetWeakPtr());
110 198
199 MaybeRecordUserMetrics(UMA_TYPE_GEOLOCATION, should_allow, user_initiated);
111 WebContents* web_contents = guest->embedder_web_contents(); 200 WebContents* web_contents = guest->embedder_web_contents();
112 if (should_allow && web_contents) { 201 if (should_allow && web_contents) {
113 // If renderer side embedder decides to allow gelocation, we need to check 202 // If renderer side embedder decides to allow gelocation, we need to check
114 // if the app/embedder itself has geolocation access. 203 // if the app/embedder itself has geolocation access.
115 BrowserContext* browser_context = web_contents->GetBrowserContext(); 204 BrowserContext* browser_context = web_contents->GetBrowserContext();
116 if (browser_context) { 205 if (browser_context) {
117 GeolocationPermissionContext* geolocation_context = 206 GeolocationPermissionContext* geolocation_context =
118 browser_context->GetGeolocationPermissionContext(); 207 browser_context->GetGeolocationPermissionContext();
119 if (geolocation_context) { 208 if (geolocation_context) {
120 base::Callback<void(bool)> geolocation_callback = base::Bind( 209 base::Callback<void(bool)> geolocation_callback = base::Bind(
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after
152 const MediaResponseCallback& callback, 241 const MediaResponseCallback& callback,
153 BrowserPluginGuest* guest) 242 BrowserPluginGuest* guest)
154 : request_(request), 243 : request_(request),
155 callback_(callback), 244 callback_(callback),
156 guest_(guest) { 245 guest_(guest) {
157 RecordAction( 246 RecordAction(
158 UserMetricsAction("BrowserPlugin.Guest.PermissionRequest.Media")); 247 UserMetricsAction("BrowserPlugin.Guest.PermissionRequest.Media"));
159 } 248 }
160 249
161 virtual void Respond(bool should_allow, 250 virtual void Respond(bool should_allow,
162 const std::string& user_input) OVERRIDE { 251 const std::string& user_input,
252 bool user_initiated) OVERRIDE {
163 WebContentsImpl* web_contents = guest_->embedder_web_contents(); 253 WebContentsImpl* web_contents = guest_->embedder_web_contents();
164 if (should_allow && web_contents) { 254 if (should_allow && web_contents) {
165 // Re-route the request to the embedder's WebContents; the guest gets the 255 // Re-route the request to the embedder's WebContents; the guest gets the
166 // permission this way. 256 // permission this way.
167 web_contents->RequestMediaAccessPermission(request_, callback_); 257 web_contents->RequestMediaAccessPermission(request_, callback_);
168 } else { 258 } else {
169 // Deny the request. 259 // Deny the request.
170 callback_.Run(MediaStreamDevices(), scoped_ptr<MediaStreamUI>()); 260 callback_.Run(MediaStreamDevices(), scoped_ptr<MediaStreamUI>());
171 } 261 }
262 MaybeRecordUserMetrics(UMA_TYPE_MEDIA, should_allow, user_initiated);
172 } 263 }
173 264
174 private: 265 private:
175 virtual ~MediaRequest() {} 266 virtual ~MediaRequest() {}
176 MediaStreamRequest request_; 267 MediaStreamRequest request_;
177 MediaResponseCallback callback_; 268 MediaResponseCallback callback_;
178 BrowserPluginGuest* guest_; 269 BrowserPluginGuest* guest_;
179 }; 270 };
180 271
181 class BrowserPluginGuest::NewWindowRequest : public PermissionRequest { 272 class BrowserPluginGuest::NewWindowRequest : public PermissionRequest {
182 public: 273 public:
183 NewWindowRequest(int instance_id, BrowserPluginGuest* guest) 274 NewWindowRequest(int instance_id, BrowserPluginGuest* guest)
184 : instance_id_(instance_id), 275 : instance_id_(instance_id),
185 guest_(guest) { 276 guest_(guest) {
186 RecordAction( 277 RecordAction(
187 UserMetricsAction("BrowserPlugin.Guest.PermissionRequest.NewWindow")); 278 UserMetricsAction("BrowserPlugin.Guest.PermissionRequest.NewWindow"));
188 } 279 }
189 280
190 virtual void Respond(bool should_allow, 281 virtual void Respond(bool should_allow,
191 const std::string& user_input) OVERRIDE { 282 const std::string& user_input,
283 bool user_initiated) OVERRIDE {
192 int embedder_render_process_id = 284 int embedder_render_process_id =
193 guest_->embedder_web_contents()->GetRenderProcessHost()->GetID(); 285 guest_->embedder_web_contents()->GetRenderProcessHost()->GetID();
194 BrowserPluginGuest* guest = 286 BrowserPluginGuest* guest =
195 guest_->GetWebContents()->GetBrowserPluginGuestManager()-> 287 guest_->GetWebContents()->GetBrowserPluginGuestManager()->
196 GetGuestByInstanceID(instance_id_, embedder_render_process_id); 288 GetGuestByInstanceID(instance_id_, embedder_render_process_id);
197 if (!guest) { 289 if (!guest) {
198 LOG(INFO) << "Guest not found. Instance ID: " << instance_id_; 290 LOG(INFO) << "Guest not found. Instance ID: " << instance_id_;
199 return; 291 return;
200 } 292 }
201 293
294 MaybeRecordUserMetrics(UMA_TYPE_NEW_WINDOW, should_allow, user_initiated);
202 // If we do not destroy the guest then we allow the new window. 295 // If we do not destroy the guest then we allow the new window.
203 if (!should_allow) 296 if (!should_allow)
204 guest->Destroy(); 297 guest->Destroy();
205 } 298 }
206 299
207 private: 300 private:
208 virtual ~NewWindowRequest() {} 301 virtual ~NewWindowRequest() {}
209 int instance_id_; 302 int instance_id_;
210 BrowserPluginGuest* guest_; 303 BrowserPluginGuest* guest_;
211 }; 304 };
212 305
213 class BrowserPluginGuest::JavaScriptDialogRequest : public PermissionRequest { 306 class BrowserPluginGuest::JavaScriptDialogRequest : public PermissionRequest {
214 public: 307 public:
215 JavaScriptDialogRequest(const DialogClosedCallback& callback) 308 JavaScriptDialogRequest(const DialogClosedCallback& callback)
216 : callback_(callback) { 309 : callback_(callback) {
217 RecordAction( 310 RecordAction(
218 UserMetricsAction( 311 UserMetricsAction(
219 "BrowserPlugin.Guest.PermissionRequest.JavaScriptDialog")); 312 "BrowserPlugin.Guest.PermissionRequest.JavaScriptDialog"));
220 } 313 }
221 314
222 virtual void Respond(bool should_allow, 315 virtual void Respond(bool should_allow,
223 const std::string& user_input) OVERRIDE { 316 const std::string& user_input,
317 bool user_initiated) OVERRIDE {
224 callback_.Run(should_allow, UTF8ToUTF16(user_input)); 318 callback_.Run(should_allow, UTF8ToUTF16(user_input));
319 MaybeRecordUserMetrics(UMA_TYPE_JAVASCRIPT_DIALOG, should_allow,
320 user_initiated);
225 } 321 }
226 322
227 private: 323 private:
228 virtual ~JavaScriptDialogRequest() {} 324 virtual ~JavaScriptDialogRequest() {}
229 DialogClosedCallback callback_; 325 DialogClosedCallback callback_;
230 }; 326 };
231 327
232 class BrowserPluginGuest::PointerLockRequest : public PermissionRequest { 328 class BrowserPluginGuest::PointerLockRequest : public PermissionRequest {
233 public: 329 public:
234 PointerLockRequest(BrowserPluginGuest* guest) 330 PointerLockRequest(BrowserPluginGuest* guest)
235 : guest_(guest) { 331 : guest_(guest) {
236 RecordAction( 332 RecordAction(
237 UserMetricsAction("BrowserPlugin.Guest.PermissionRequest.PointerLock")); 333 UserMetricsAction("BrowserPlugin.Guest.PermissionRequest.PointerLock"));
238 } 334 }
239 335
240 virtual void Respond(bool should_allow, 336 virtual void Respond(bool should_allow,
241 const std::string& user_input) OVERRIDE { 337 const std::string& user_input,
338 bool user_initiated) OVERRIDE {
242 guest_->SendMessageToEmbedder( 339 guest_->SendMessageToEmbedder(
243 new BrowserPluginMsg_SetMouseLock(guest_->instance_id(), should_allow)); 340 new BrowserPluginMsg_SetMouseLock(guest_->instance_id(), should_allow));
341 MaybeRecordUserMetrics(UMA_TYPE_POINTER_LOCK, should_allow, user_initiated);
244 } 342 }
245 343
246 private: 344 private:
247 virtual ~PointerLockRequest() {} 345 virtual ~PointerLockRequest() {}
248 BrowserPluginGuest* guest_; 346 BrowserPluginGuest* guest_;
249 }; 347 };
250 348
251 namespace { 349 namespace {
252 std::string WindowOpenDispositionToString( 350 std::string WindowOpenDispositionToString(
253 WindowOpenDisposition window_open_disposition) { 351 WindowOpenDisposition window_open_disposition) {
(...skipping 148 matching lines...) Expand 10 before | Expand all | Expand 10 after
402 if (delegate_ && delegate_->IsOverridingUserAgent()) { 500 if (delegate_ && delegate_->IsOverridingUserAgent()) {
403 load_url_params.override_user_agent = 501 load_url_params.override_user_agent =
404 NavigationController::UA_OVERRIDE_TRUE; 502 NavigationController::UA_OVERRIDE_TRUE;
405 } 503 }
406 web_contents->GetController().LoadURLWithParams(load_url_params); 504 web_contents->GetController().LoadURLWithParams(load_url_params);
407 } 505 }
408 506
409 void BrowserPluginGuest::RespondToPermissionRequest( 507 void BrowserPluginGuest::RespondToPermissionRequest(
410 int request_id, 508 int request_id,
411 bool should_allow, 509 bool should_allow,
412 const std::string& user_input) { 510 const std::string& user_input,
511 bool user_initiated) {
413 RequestMap::iterator request_itr = permission_request_map_.find(request_id); 512 RequestMap::iterator request_itr = permission_request_map_.find(request_id);
414 if (request_itr == permission_request_map_.end()) { 513 if (request_itr == permission_request_map_.end()) {
415 LOG(INFO) << "Not a valid request ID."; 514 LOG(INFO) << "Not a valid request ID.";
416 return; 515 return;
417 } 516 }
418 request_itr->second->Respond(should_allow, user_input); 517 request_itr->second->Respond(should_allow, user_input, user_initiated);
419 permission_request_map_.erase(request_itr); 518 permission_request_map_.erase(request_itr);
420 } 519 }
421 520
422 int BrowserPluginGuest::RequestPermission( 521 int BrowserPluginGuest::RequestPermission(
423 BrowserPluginPermissionType permission_type, 522 BrowserPluginPermissionType permission_type,
424 scoped_refptr<BrowserPluginGuest::PermissionRequest> request, 523 scoped_refptr<BrowserPluginGuest::PermissionRequest> request,
425 const base::DictionaryValue& request_info) { 524 const base::DictionaryValue& request_info) {
426 if (!delegate_) { 525 if (!delegate_) {
427 request->Respond(false, ""); 526 request->Respond(false, "", false);
428 return browser_plugin::kInvalidPermissionRequestID; 527 return browser_plugin::kInvalidPermissionRequestID;
429 } 528 }
430 529
431 int request_id = ++next_permission_request_id_; 530 int request_id = ++next_permission_request_id_;
432 permission_request_map_[request_id] = request; 531 permission_request_map_[request_id] = request;
433 532
434 BrowserPluginGuestDelegate::PermissionResponseCallback callback = 533 BrowserPluginGuestDelegate::PermissionResponseCallback callback =
435 base::Bind(&BrowserPluginGuest::RespondToPermissionRequest, 534 base::Bind(&BrowserPluginGuest::RespondToPermissionRequest,
436 AsWeakPtr(), 535 AsWeakPtr(),
437 request_id); 536 request_id);
438 // If BrowserPluginGuestDelegate hasn't handled the permission then we simply 537 // If BrowserPluginGuestDelegate hasn't handled the permission then we simply
439 // reject it immediately. 538 // perform the default action (which is one of allow or reject) immediately.
440 if (!delegate_->RequestPermission( 539 if (!delegate_->RequestPermission(
441 permission_type, request_info, callback, request->AllowedByDefault())) { 540 permission_type, request_info, callback, request->AllowedByDefault())) {
442 callback.Run(request->AllowedByDefault(), ""); 541 callback.Run(request->AllowedByDefault(), "", false);
443 return browser_plugin::kInvalidPermissionRequestID; 542 return browser_plugin::kInvalidPermissionRequestID;
444 } 543 }
445 544
446 return request_id; 545 return request_id;
447 } 546 }
448 547
449 BrowserPluginGuest* BrowserPluginGuest::CreateNewGuestWindow( 548 BrowserPluginGuest* BrowserPluginGuest::CreateNewGuestWindow(
450 const OpenURLParams& params) { 549 const OpenURLParams& params) {
451 BrowserPluginGuestManager* guest_manager = 550 BrowserPluginGuestManager* guest_manager =
452 GetWebContents()->GetBrowserPluginGuestManager(); 551 GetWebContents()->GetBrowserPluginGuestManager();
(...skipping 1278 matching lines...) Expand 10 before | Expand all | Expand 10 after
1731 request_info.Set(browser_plugin::kRequestMethod, 1830 request_info.Set(browser_plugin::kRequestMethod,
1732 base::Value::CreateStringValue(request_method)); 1831 base::Value::CreateStringValue(request_method));
1733 request_info.Set(browser_plugin::kURL, base::Value::CreateStringValue(url)); 1832 request_info.Set(browser_plugin::kURL, base::Value::CreateStringValue(url));
1734 1833
1735 RequestPermission(BROWSER_PLUGIN_PERMISSION_TYPE_DOWNLOAD, 1834 RequestPermission(BROWSER_PLUGIN_PERMISSION_TYPE_DOWNLOAD,
1736 new DownloadRequest(callback), 1835 new DownloadRequest(callback),
1737 request_info); 1836 request_info);
1738 } 1837 }
1739 1838
1740 } // namespace content 1839 } // namespace content
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698