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

Side by Side Diff: chrome/browser/ui/website_settings/permission_bubble_manager.cc

Issue 1610753002: Fixes Permission Bubbles never responding to duplicate requests (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Fix tests and RequestFinishedIncludingDuplicates DCHECK Created 4 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 2014 The Chromium Authors. All rights reserved. 1 // Copyright 2014 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/ui/website_settings/permission_bubble_manager.h" 5 #include "chrome/browser/ui/website_settings/permission_bubble_manager.h"
6 6
7 #include <algorithm>
8
7 #include "base/command_line.h" 9 #include "base/command_line.h"
8 #include "base/metrics/user_metrics_action.h" 10 #include "base/metrics/user_metrics_action.h"
9 #include "build/build_config.h" 11 #include "build/build_config.h"
10 #include "chrome/browser/ui/website_settings/permission_bubble_request.h" 12 #include "chrome/browser/ui/website_settings/permission_bubble_request.h"
11 #include "chrome/common/chrome_switches.h" 13 #include "chrome/common/chrome_switches.h"
12 #include "content/public/browser/browser_thread.h" 14 #include "content/public/browser/browser_thread.h"
13 #include "content/public/browser/navigation_details.h" 15 #include "content/public/browser/navigation_details.h"
14 #include "content/public/browser/user_metrics.h" 16 #include "content/public/browser/user_metrics.h"
15 #include "url/origin.h" 17 #include "url/origin.h"
16 18
(...skipping 29 matching lines...) Expand all
46 void RequestFinished() override { delete this; } 48 void RequestFinished() override { delete this; }
47 49
48 private: 50 private:
49 int icon_; 51 int icon_;
50 base::string16 message_text_; 52 base::string16 message_text_;
51 base::string16 message_fragment_; 53 base::string16 message_fragment_;
52 bool user_gesture_; 54 bool user_gesture_;
53 GURL origin_; 55 GURL origin_;
54 }; 56 };
55 57
58 bool IsMessageTextEqual(PermissionBubbleRequest* a,
59 PermissionBubbleRequest* b) {
60 if (a == b)
61 return true;
62 if (a->GetMessageTextFragment() == b->GetMessageTextFragment() &&
63 a->GetOrigin() == b->GetOrigin()) {
64 return true;
65 }
66 return false;
67 }
68
56 } // namespace 69 } // namespace
57 70
58 // PermissionBubbleManager::Observer ------------------------------------------- 71 // PermissionBubbleManager::Observer -------------------------------------------
59 72
60 PermissionBubbleManager::Observer::~Observer() { 73 PermissionBubbleManager::Observer::~Observer() {
61 } 74 }
62 75
63 void PermissionBubbleManager::Observer::OnBubbleAdded() { 76 void PermissionBubbleManager::Observer::OnBubbleAdded() {
64 } 77 }
65 78
(...skipping 10 matching lines...) Expand all
76 view_(nullptr), 89 view_(nullptr),
77 main_frame_has_fully_loaded_(false), 90 main_frame_has_fully_loaded_(false),
78 auto_response_for_test_(NONE), 91 auto_response_for_test_(NONE),
79 weak_factory_(this) { 92 weak_factory_(this) {
80 } 93 }
81 94
82 PermissionBubbleManager::~PermissionBubbleManager() { 95 PermissionBubbleManager::~PermissionBubbleManager() {
83 if (view_ != NULL) 96 if (view_ != NULL)
84 view_->SetDelegate(NULL); 97 view_->SetDelegate(NULL);
85 98
86 std::vector<PermissionBubbleRequest*>::iterator requests_iter; 99 for (PermissionBubbleRequest* request : requests_)
87 for (requests_iter = requests_.begin(); 100 request->RequestFinished();
88 requests_iter != requests_.end(); 101 for (PermissionBubbleRequest* request : queued_requests_)
89 requests_iter++) { 102 request->RequestFinished();
90 (*requests_iter)->RequestFinished(); 103 for (PermissionBubbleRequest* request : queued_frame_requests_)
91 } 104 request->RequestFinished();
92 for (requests_iter = queued_requests_.begin(); 105 for (const auto& entry : duplicate_requests_)
93 requests_iter != queued_requests_.end(); 106 entry.second->RequestFinished();
94 requests_iter++) {
95 (*requests_iter)->RequestFinished();
96 }
97 } 107 }
98 108
99 void PermissionBubbleManager::AddRequest(PermissionBubbleRequest* request) { 109 void PermissionBubbleManager::AddRequest(PermissionBubbleRequest* request) {
100 content::RecordAction(base::UserMetricsAction("PermissionBubbleRequest")); 110 content::RecordAction(base::UserMetricsAction("PermissionBubbleRequest"));
101 // TODO(gbillock): is there a race between an early request on a 111 // TODO(gbillock): is there a race between an early request on a
102 // newly-navigated page and the to-be-cleaned-up requests on the previous 112 // newly-navigated page and the to-be-cleaned-up requests on the previous
103 // page? We should maybe listen to DidStartNavigationToPendingEntry (and 113 // page? We should maybe listen to DidStartNavigationToPendingEntry (and
104 // any other renderer-side nav initiations?). Double-check this for 114 // any other renderer-side nav initiations?). Double-check this for
105 // correct behavior on interstitials -- we probably want to basically queue 115 // correct behavior on interstitials -- we probably want to basically queue
106 // any request for which GetVisibleURL != GetLastCommittedURL. 116 // any request for which GetVisibleURL != GetLastCommittedURL.
107 request_url_ = web_contents()->GetLastCommittedURL(); 117 request_url_ = web_contents()->GetLastCommittedURL();
108 bool is_main_frame = url::Origin(request_url_) 118 bool is_main_frame = url::Origin(request_url_)
109 .IsSameOriginWith(url::Origin(request->GetOrigin())); 119 .IsSameOriginWith(url::Origin(request->GetOrigin()));
110 120
111 // Don't re-add an existing request or one with a duplicate text request. 121 // Don't re-add an existing request or one with a duplicate text request.
112 // TODO(johnme): Instead of dropping duplicate requests, we should queue them 122 PermissionBubbleRequest* existing_request = GetExistingRequest(request);
113 // and eventually run their PermissionGranted/PermissionDenied/Cancelled 123 if (existing_request) {
114 // callback (crbug.com/577313). 124 // |request| is a duplicate. Add it to |duplicate_requests_| unless it's the
115 bool same_object = false; 125 // same object as |existing_request| or an existing duplicate.
116 if (ExistingRequest(request, requests_, &same_object) || 126 if (request == existing_request)
117 ExistingRequest(request, queued_requests_, &same_object) || 127 return;
118 ExistingRequest(request, queued_frame_requests_, &same_object)) { 128 auto range = duplicate_requests_.equal_range(existing_request);
119 if (!same_object) 129 for (auto it = range.first; it != range.second; ++it) {
120 request->RequestFinished(); 130 if (request == it->second)
131 return;
132 }
133 duplicate_requests_.insert(std::make_pair(existing_request, request));
121 return; 134 return;
122 } 135 }
123 136
124 if (IsBubbleVisible()) { 137 if (IsBubbleVisible()) {
125 if (is_main_frame) { 138 if (is_main_frame) {
126 content::RecordAction( 139 content::RecordAction(
127 base::UserMetricsAction("PermissionBubbleRequestQueued")); 140 base::UserMetricsAction("PermissionBubbleRequestQueued"));
128 queued_requests_.push_back(request); 141 queued_requests_.push_back(request);
129 } else { 142 } else {
130 content::RecordAction( 143 content::RecordAction(
(...skipping 10 matching lines...) Expand all
141 } else { 154 } else {
142 content::RecordAction( 155 content::RecordAction(
143 base::UserMetricsAction("PermissionBubbleIFrameRequestQueued")); 156 base::UserMetricsAction("PermissionBubbleIFrameRequestQueued"));
144 queued_frame_requests_.push_back(request); 157 queued_frame_requests_.push_back(request);
145 } 158 }
146 159
147 ScheduleShowBubble(); 160 ScheduleShowBubble();
148 } 161 }
149 162
150 void PermissionBubbleManager::CancelRequest(PermissionBubbleRequest* request) { 163 void PermissionBubbleManager::CancelRequest(PermissionBubbleRequest* request) {
151 // First look in the queued requests, where we can simply delete the request 164 // First look in the queued requests, where we can simply finish the request
152 // and go on. 165 // and go on.
153 std::vector<PermissionBubbleRequest*>::iterator requests_iter; 166 std::vector<PermissionBubbleRequest*>::iterator requests_iter;
154 for (requests_iter = queued_requests_.begin(); 167 for (requests_iter = queued_requests_.begin();
155 requests_iter != queued_requests_.end(); 168 requests_iter != queued_requests_.end();
156 requests_iter++) { 169 requests_iter++) {
157 if (*requests_iter == request) { 170 if (*requests_iter == request) {
158 (*requests_iter)->RequestFinished(); 171 RequestFinishedIncludingDuplicates(*requests_iter);
159 queued_requests_.erase(requests_iter); 172 queued_requests_.erase(requests_iter);
160 return; 173 return;
161 } 174 }
162 } 175 }
176 for (requests_iter = queued_frame_requests_.begin();
177 requests_iter != queued_frame_requests_.end(); requests_iter++) {
178 if (*requests_iter == request) {
179 RequestFinishedIncludingDuplicates(*requests_iter);
180 queued_frame_requests_.erase(requests_iter);
181 return;
182 }
183 }
163 184
164 std::vector<bool>::iterator accepts_iter = accept_states_.begin(); 185 std::vector<bool>::iterator accepts_iter = accept_states_.begin();
165 for (requests_iter = requests_.begin(), accepts_iter = accept_states_.begin(); 186 for (requests_iter = requests_.begin(), accepts_iter = accept_states_.begin();
166 requests_iter != requests_.end(); 187 requests_iter != requests_.end();
167 requests_iter++, accepts_iter++) { 188 requests_iter++, accepts_iter++) {
168 if (*requests_iter != request) 189 if (*requests_iter != request)
169 continue; 190 continue;
170 191
171 // We can simply erase the current entry in the request table if we aren't 192 // We can simply erase the current entry in the request table if we aren't
172 // showing the dialog, or if we are showing it and it can accept the update. 193 // showing the dialog, or if we are showing it and it can accept the update.
173 bool can_erase = !IsBubbleVisible() || view_->CanAcceptRequestUpdate(); 194 bool can_erase = !IsBubbleVisible() || view_->CanAcceptRequestUpdate();
174 if (can_erase) { 195 if (can_erase) {
175 (*requests_iter)->RequestFinished(); 196 RequestFinishedIncludingDuplicates(*requests_iter);
176 requests_.erase(requests_iter); 197 requests_.erase(requests_iter);
177 accept_states_.erase(accepts_iter); 198 accept_states_.erase(accepts_iter);
178 199
179 if (IsBubbleVisible()) { 200 if (IsBubbleVisible()) {
180 view_->Hide(); 201 view_->Hide();
181 // Will redraw the bubble if it is being shown. 202 // Will redraw the bubble if it is being shown.
182 TriggerShowBubble(); 203 TriggerShowBubble();
183 } 204 }
184 return; 205 return;
185 } 206 }
186 207
187 // Cancel the existing request and replace it with a dummy. 208 // Cancel the existing request and replace it with a dummy.
188 PermissionBubbleRequest* cancelled_request = 209 PermissionBubbleRequest* cancelled_request =
189 new CancelledRequest(*requests_iter); 210 new CancelledRequest(*requests_iter);
190 (*requests_iter)->RequestFinished(); 211 RequestFinishedIncludingDuplicates(*requests_iter);
191 *requests_iter = cancelled_request; 212 *requests_iter = cancelled_request;
192 return; 213 return;
193 } 214 }
194 215
216 // Since |request| wasn't found in queued_requests_, queued_frame_requests_ or
217 // requests_ it must have been marked as a duplicate. We can't search
218 // duplicate_requests_ by value, so instead use GetExistingRequest to find the
219 // key (request it was duped against), and iterate through duplicates of that.
220 PermissionBubbleRequest* existing_request = GetExistingRequest(request);
221 auto range = duplicate_requests_.equal_range(existing_request);
222 for (auto it = range.first; it != range.second; ++it) {
223 if (request == it->second) {
224 it->second->RequestFinished();
225 duplicate_requests_.erase(it);
226 return;
227 }
228 }
229
195 NOTREACHED(); // Callers should not cancel requests that are not pending. 230 NOTREACHED(); // Callers should not cancel requests that are not pending.
196 } 231 }
197 232
198 void PermissionBubbleManager::HideBubble() { 233 void PermissionBubbleManager::HideBubble() {
199 // Disengage from the existing view if there is one. 234 // Disengage from the existing view if there is one.
200 if (!view_) 235 if (!view_)
201 return; 236 return;
202 237
203 view_->SetDelegate(nullptr); 238 view_->SetDelegate(nullptr);
204 view_->Hide(); 239 view_->Hide();
(...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after
278 DCHECK(request_index < static_cast<int>(accept_states_.size())); 313 DCHECK(request_index < static_cast<int>(accept_states_.size()));
279 accept_states_[request_index] = new_value; 314 accept_states_[request_index] = new_value;
280 } 315 }
281 316
282 void PermissionBubbleManager::Accept() { 317 void PermissionBubbleManager::Accept() {
283 std::vector<PermissionBubbleRequest*>::iterator requests_iter; 318 std::vector<PermissionBubbleRequest*>::iterator requests_iter;
284 std::vector<bool>::iterator accepts_iter = accept_states_.begin(); 319 std::vector<bool>::iterator accepts_iter = accept_states_.begin();
285 for (requests_iter = requests_.begin(), accepts_iter = accept_states_.begin(); 320 for (requests_iter = requests_.begin(), accepts_iter = accept_states_.begin();
286 requests_iter != requests_.end(); 321 requests_iter != requests_.end();
287 requests_iter++, accepts_iter++) { 322 requests_iter++, accepts_iter++) {
288 if (*accepts_iter) 323 if (*accepts_iter) {
289 (*requests_iter)->PermissionGranted(); 324 PermissionGrantedIncludingDuplicates(*requests_iter);
290 else 325 } else {
291 (*requests_iter)->PermissionDenied(); 326 PermissionDeniedIncludingDuplicates(*requests_iter);
327 }
292 } 328 }
293 FinalizeBubble(); 329 FinalizeBubble();
294 } 330 }
295 331
296 void PermissionBubbleManager::Deny() { 332 void PermissionBubbleManager::Deny() {
297 std::vector<PermissionBubbleRequest*>::iterator requests_iter; 333 std::vector<PermissionBubbleRequest*>::iterator requests_iter;
298 for (requests_iter = requests_.begin(); 334 for (requests_iter = requests_.begin();
299 requests_iter != requests_.end(); 335 requests_iter != requests_.end();
300 requests_iter++) { 336 requests_iter++) {
301 (*requests_iter)->PermissionDenied(); 337 PermissionDeniedIncludingDuplicates(*requests_iter);
302 } 338 }
303 FinalizeBubble(); 339 FinalizeBubble();
304 } 340 }
305 341
306 void PermissionBubbleManager::Closing() { 342 void PermissionBubbleManager::Closing() {
307 std::vector<PermissionBubbleRequest*>::iterator requests_iter; 343 std::vector<PermissionBubbleRequest*>::iterator requests_iter;
308 for (requests_iter = requests_.begin(); 344 for (requests_iter = requests_.begin();
309 requests_iter != requests_.end(); 345 requests_iter != requests_.end();
310 requests_iter++) { 346 requests_iter++) {
311 (*requests_iter)->Cancelled(); 347 CancelledIncludingDuplicates(*requests_iter);
312 } 348 }
313 FinalizeBubble(); 349 FinalizeBubble();
314 } 350 }
315 351
316 void PermissionBubbleManager::ScheduleShowBubble() { 352 void PermissionBubbleManager::ScheduleShowBubble() {
317 // ::ScheduleShowBubble() will be called again when the main frame will be 353 // ::ScheduleShowBubble() will be called again when the main frame will be
318 // loaded. 354 // loaded.
319 if (!main_frame_has_fully_loaded_) 355 if (!main_frame_has_fully_loaded_)
320 return; 356 return;
321 357
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after
365 } 401 }
366 402
367 void PermissionBubbleManager::FinalizeBubble() { 403 void PermissionBubbleManager::FinalizeBubble() {
368 if (view_) 404 if (view_)
369 view_->Hide(); 405 view_->Hide();
370 406
371 std::vector<PermissionBubbleRequest*>::iterator requests_iter; 407 std::vector<PermissionBubbleRequest*>::iterator requests_iter;
372 for (requests_iter = requests_.begin(); 408 for (requests_iter = requests_.begin();
373 requests_iter != requests_.end(); 409 requests_iter != requests_.end();
374 requests_iter++) { 410 requests_iter++) {
375 (*requests_iter)->RequestFinished(); 411 RequestFinishedIncludingDuplicates(*requests_iter);
376 } 412 }
377 requests_.clear(); 413 requests_.clear();
378 accept_states_.clear(); 414 accept_states_.clear();
379 if (queued_requests_.size() || queued_frame_requests_.size()) 415 if (queued_requests_.size() || queued_frame_requests_.size())
380 TriggerShowBubble(); 416 TriggerShowBubble();
381 else 417 else
382 request_url_ = GURL(); 418 request_url_ = GURL();
383 } 419 }
384 420
385 void PermissionBubbleManager::CancelPendingQueues() { 421 void PermissionBubbleManager::CancelPendingQueues() {
386 std::vector<PermissionBubbleRequest*>::iterator requests_iter; 422 std::vector<PermissionBubbleRequest*>::iterator requests_iter;
387 for (requests_iter = queued_requests_.begin(); 423 for (requests_iter = queued_requests_.begin();
388 requests_iter != queued_requests_.end(); 424 requests_iter != queued_requests_.end();
389 requests_iter++) { 425 requests_iter++) {
390 (*requests_iter)->RequestFinished(); 426 RequestFinishedIncludingDuplicates(*requests_iter);
391 } 427 }
392 for (requests_iter = queued_frame_requests_.begin(); 428 for (requests_iter = queued_frame_requests_.begin();
393 requests_iter != queued_frame_requests_.end(); 429 requests_iter != queued_frame_requests_.end();
394 requests_iter++) { 430 requests_iter++) {
395 (*requests_iter)->RequestFinished(); 431 RequestFinishedIncludingDuplicates(*requests_iter);
396 } 432 }
397 queued_requests_.clear(); 433 queued_requests_.clear();
398 queued_frame_requests_.clear(); 434 queued_frame_requests_.clear();
399 } 435 }
400 436
401 bool PermissionBubbleManager::ExistingRequest( 437 PermissionBubbleRequest* PermissionBubbleManager::GetExistingRequest(
402 PermissionBubbleRequest* request, 438 PermissionBubbleRequest* request) {
403 const std::vector<PermissionBubbleRequest*>& queue, 439 for (PermissionBubbleRequest* existing_request : requests_)
404 bool* same_object) { 440 if (IsMessageTextEqual(existing_request, request))
405 CHECK(same_object); 441 return existing_request;
406 *same_object = false; 442 for (PermissionBubbleRequest* existing_request : queued_requests_)
407 std::vector<PermissionBubbleRequest*>::const_iterator iter; 443 if (IsMessageTextEqual(existing_request, request))
408 for (iter = queue.begin(); iter != queue.end(); iter++) { 444 return existing_request;
409 if (*iter == request) { 445 for (PermissionBubbleRequest* existing_request : queued_frame_requests_)
410 *same_object = true; 446 if (IsMessageTextEqual(existing_request, request))
411 return true; 447 return existing_request;
412 } 448 return nullptr;
413 if ((*iter)->GetMessageTextFragment() ==
414 request->GetMessageTextFragment() &&
415 (*iter)->GetOrigin() == request->GetOrigin()) {
416 return true;
417 }
418 }
419 return false;
420 } 449 }
421 450
422 bool PermissionBubbleManager::HasUserGestureRequest( 451 bool PermissionBubbleManager::HasUserGestureRequest(
423 const std::vector<PermissionBubbleRequest*>& queue) { 452 const std::vector<PermissionBubbleRequest*>& queue) {
424 std::vector<PermissionBubbleRequest*>::const_iterator iter; 453 std::vector<PermissionBubbleRequest*>::const_iterator iter;
425 for (iter = queue.begin(); iter != queue.end(); iter++) { 454 for (iter = queue.begin(); iter != queue.end(); iter++) {
426 if ((*iter)->HasUserGesture()) 455 if ((*iter)->HasUserGesture())
427 return true; 456 return true;
428 } 457 }
429 return false; 458 return false;
430 } 459 }
431 460
461 void PermissionBubbleManager::PermissionGrantedIncludingDuplicates(
462 PermissionBubbleRequest* request) {
463 DCHECK_EQ(request, GetExistingRequest(request))
464 << "Only requests in [queued_[frame_]]requests_ can have duplicates";
465 request->PermissionGranted();
466 auto range = duplicate_requests_.equal_range(request);
467 for (auto it = range.first; it != range.second; ++it)
468 it->second->PermissionGranted();
469 }
470 void PermissionBubbleManager::PermissionDeniedIncludingDuplicates(
471 PermissionBubbleRequest* request) {
472 DCHECK_EQ(request, GetExistingRequest(request))
473 << "Only requests in [queued_[frame_]]requests_ can have duplicates";
474 request->PermissionDenied();
475 auto range = duplicate_requests_.equal_range(request);
476 for (auto it = range.first; it != range.second; ++it)
477 it->second->PermissionDenied();
478 }
479 void PermissionBubbleManager::CancelledIncludingDuplicates(
480 PermissionBubbleRequest* request) {
481 DCHECK_EQ(request, GetExistingRequest(request))
482 << "Only requests in [queued_[frame_]]requests_ can have duplicates";
483 request->Cancelled();
484 auto range = duplicate_requests_.equal_range(request);
485 for (auto it = range.first; it != range.second; ++it)
486 it->second->Cancelled();
487 }
488 void PermissionBubbleManager::RequestFinishedIncludingDuplicates(
489 PermissionBubbleRequest* request) {
490 // We can't call GetExistingRequest here, because other entries in requests_,
491 // queued_requests_ or queued_frame_requests_ might already have been deleted.
492 DCHECK_EQ(1, std::count(requests_.begin(), requests_.end(), request) +
493 std::count(queued_requests_.begin(), queued_requests_.end(),
494 request) +
495 std::count(queued_frame_requests_.begin(),
496 queued_frame_requests_.end(), request))
497 << "Only requests in [queued_[frame_]]requests_ can have duplicates";
498 request->RequestFinished();
499 // Beyond this point, |request| has probably been deleted.
500 auto range = duplicate_requests_.equal_range(request);
501 for (auto it = range.first; it != range.second; ++it)
502 it->second->RequestFinished();
503 // Additionally, we can now remove the duplicates.
504 duplicate_requests_.erase(request);
505 }
506
432 void PermissionBubbleManager::AddObserver(Observer* observer) { 507 void PermissionBubbleManager::AddObserver(Observer* observer) {
433 observer_list_.AddObserver(observer); 508 observer_list_.AddObserver(observer);
434 } 509 }
435 510
436 void PermissionBubbleManager::RemoveObserver(Observer* observer) { 511 void PermissionBubbleManager::RemoveObserver(Observer* observer) {
437 observer_list_.RemoveObserver(observer); 512 observer_list_.RemoveObserver(observer);
438 } 513 }
439 514
440 void PermissionBubbleManager::NotifyBubbleAdded() { 515 void PermissionBubbleManager::NotifyBubbleAdded() {
441 FOR_EACH_OBSERVER(Observer, observer_list_, OnBubbleAdded()); 516 FOR_EACH_OBSERVER(Observer, observer_list_, OnBubbleAdded());
442 } 517 }
443 518
444 void PermissionBubbleManager::DoAutoResponseForTesting() { 519 void PermissionBubbleManager::DoAutoResponseForTesting() {
445 switch (auto_response_for_test_) { 520 switch (auto_response_for_test_) {
446 case ACCEPT_ALL: 521 case ACCEPT_ALL:
447 Accept(); 522 Accept();
448 break; 523 break;
449 case DENY_ALL: 524 case DENY_ALL:
450 Deny(); 525 Deny();
451 break; 526 break;
452 case DISMISS: 527 case DISMISS:
453 Closing(); 528 Closing();
454 break; 529 break;
455 case NONE: 530 case NONE:
456 NOTREACHED(); 531 NOTREACHED();
457 } 532 }
458 } 533 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698