permission_bubble_manager.cc revision c5cede9ae108bb15f6b7a8aea21c7e1fefa2834c
15d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// Copyright 2014 The Chromium Authors. All rights reserved. 25d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 35d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// found in the LICENSE file. 45d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 55d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "chrome/browser/ui/website_settings/permission_bubble_manager.h" 65d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 75d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "base/command_line.h" 85d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "chrome/browser/ui/website_settings/permission_bubble_request.h" 95d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "chrome/common/chrome_switches.h" 105d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 115d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)DEFINE_WEB_CONTENTS_USER_DATA_KEY(PermissionBubbleManager); 125d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 135d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)namespace { 145d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 155d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// This is how many ms to wait to see if there's another permission request 165d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// we should coalesce. 175d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)const int kPermissionsCoalesceIntervalMs = 400; 185d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 195d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)} 205d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 215d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// static 225d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)bool PermissionBubbleManager::Enabled() { 235d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) return CommandLine::ForCurrentProcess()->HasSwitch( 245d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) switches::kEnablePermissionsBubbles); 255d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)} 265d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 27a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 28a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 29a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)PermissionBubbleManager::PermissionBubbleManager( 30a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) content::WebContents* web_contents) 31a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) : content::WebContentsObserver(web_contents), 32a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) bubble_showing_(false), 33a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) view_(NULL), 34a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) customization_mode_(false) { 35a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) timer_.reset(new base::Timer(FROM_HERE, 36a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) base::TimeDelta::FromMilliseconds(kPermissionsCoalesceIntervalMs), 37a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) base::Bind(&PermissionBubbleManager::ShowBubble, base::Unretained(this)), 38a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) false)); 39a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)} 40a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 41a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)PermissionBubbleManager::~PermissionBubbleManager() { 42a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) if (view_ != NULL) 43a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) view_->SetDelegate(NULL); 44a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 45a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) std::vector<PermissionBubbleRequest*>::iterator requests_iter; 46a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) for (requests_iter = requests_.begin(); 47a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) requests_iter != requests_.end(); 48a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) requests_iter++) { 49a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) (*requests_iter)->RequestFinished(); 50a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) } 51a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) for (requests_iter = queued_requests_.begin(); 52a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) requests_iter != queued_requests_.end(); 53a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) requests_iter++) { 54a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) (*requests_iter)->RequestFinished(); 55a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) } 56a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)} 57a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 585d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void PermissionBubbleManager::AddRequest(PermissionBubbleRequest* request) { 59a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // Don't re-add an existing request or one with a duplicate text request. 605d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) std::vector<PermissionBubbleRequest*>::iterator requests_iter; 615d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) for (requests_iter = requests_.begin(); 625d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) requests_iter != requests_.end(); 635d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) requests_iter++) { 645d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (*requests_iter == request) 655d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) return; 66a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // TODO(gbillock): worry about the requesting host name as well. 67a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) if ((*requests_iter)->GetMessageTextFragment() == 68a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) request->GetMessageTextFragment()) { 69a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) request->RequestFinished(); 70a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) return; 71a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) } 72a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) } 73a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) for (requests_iter = queued_requests_.begin(); 74a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) requests_iter != queued_requests_.end(); 75a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) requests_iter++) { 76a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) if (*requests_iter == request) 77a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) return; 78a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) if ((*requests_iter)->GetMessageTextFragment() == 79a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) request->GetMessageTextFragment()) { 80a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) request->RequestFinished(); 81a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) return; 82a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) } 835d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 845d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 855d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (bubble_showing_) { 865d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) queued_requests_.push_back(request); 875d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) return; 885d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 895d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 905d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) requests_.push_back(request); 915d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // TODO(gbillock): do we need to make default state a request property? 925d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) accept_states_.push_back(true); 935d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 945d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // Start the timer when there is both a view and a request. 955d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (view_ && !timer_->IsRunning()) 965d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) timer_->Reset(); 975d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)} 985d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 99a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)void PermissionBubbleManager::CancelRequest(PermissionBubbleRequest* request) { 100a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // TODO(gbillock): implement 101a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) NOTREACHED(); 102a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)} 103a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 1045d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void PermissionBubbleManager::SetView(PermissionBubbleView* view) { 1055d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (view == view_) 1065d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) return; 1075d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 1085d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (view_ != NULL) { 1095d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) view_->SetDelegate(NULL); 1105d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) view_->Hide(); 1115d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) bubble_showing_ = false; 1125d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 1135d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 1145d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) view_ = view; 1155d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (view_) 1165d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) view_->SetDelegate(this); 1175d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) else 1185d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) return; 1195d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 1205d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // Even if there are requests queued up, add a short delay before the bubble 1215d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // appears. 1225d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (!requests_.empty() && !timer_->IsRunning()) 1235d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) timer_->Reset(); 1245d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) else 1255d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) view_->Hide(); 1265d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)} 1275d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 1285d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void PermissionBubbleManager::DidFinishLoad( 1295d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) int64 frame_id, 1305d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) const GURL& validated_url, 1315d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) bool is_main_frame, 1325d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) content::RenderViewHost* render_view_host) { 1335d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // Allows extra time for additional requests to coalesce. 1345d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (timer_->IsRunning()) 1355d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) timer_->Reset(); 1365d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)} 1375d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 1385d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void PermissionBubbleManager::WebContentsDestroyed( 1395d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) content::WebContents* web_contents) { 140c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch // If the web contents has been destroyed, do not attempt to notify 141c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch // the requests of any changes - simply close the bubble. 142c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch FinalizeBubble(); 1435d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 1445d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // The WebContents is going away; be aggressively paranoid and delete 1455d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // ourselves lest other parts of the system attempt to add permission bubbles 1465d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // or use us otherwise during the destruction. 1475d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) web_contents->RemoveUserData(UserDataKey()); 1485d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // That was the equivalent of "delete this". This object is now destroyed; 1495d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // returning from this function is the only safe thing to do. 1505d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)} 1515d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 1525d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void PermissionBubbleManager::ToggleAccept(int request_index, bool new_value) { 1535d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) DCHECK(request_index < static_cast<int>(accept_states_.size())); 1545d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) accept_states_[request_index] = new_value; 1555d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)} 1565d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 1575d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void PermissionBubbleManager::SetCustomizationMode() { 1585d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) customization_mode_ = true; 1595d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (view_) 1605d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) view_->Show(requests_, accept_states_, customization_mode_); 1615d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)} 1625d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 1635d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void PermissionBubbleManager::Accept() { 1645d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) std::vector<PermissionBubbleRequest*>::iterator requests_iter; 1655d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) std::vector<bool>::iterator accepts_iter = accept_states_.begin(); 1665d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) for (requests_iter = requests_.begin(), accepts_iter = accept_states_.begin(); 1675d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) requests_iter != requests_.end(); 1685d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) requests_iter++, accepts_iter++) { 1695d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (*accepts_iter) 1705d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) (*requests_iter)->PermissionGranted(); 1715d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) else 1725d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) (*requests_iter)->PermissionDenied(); 1735d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 1745d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) FinalizeBubble(); 1755d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)} 1765d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 1775d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void PermissionBubbleManager::Deny() { 1785d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) std::vector<PermissionBubbleRequest*>::iterator requests_iter; 1795d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) for (requests_iter = requests_.begin(); 1805d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) requests_iter != requests_.end(); 1815d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) requests_iter++) { 1825d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) (*requests_iter)->PermissionDenied(); 1835d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 1845d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) FinalizeBubble(); 1855d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)} 1865d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 1875d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void PermissionBubbleManager::Closing() { 1885d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) std::vector<PermissionBubbleRequest*>::iterator requests_iter; 1895d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) for (requests_iter = requests_.begin(); 1905d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) requests_iter != requests_.end(); 1915d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) requests_iter++) { 1925d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) (*requests_iter)->Cancelled(); 1935d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 1945d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) FinalizeBubble(); 1955d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)} 1965d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 1975d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void PermissionBubbleManager::ShowBubble() { 1985d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (view_ && !bubble_showing_ && requests_.size()) { 199a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // Note: this should appear above Show() for testing, since in that 200a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // case we may do in-line calling of finalization. 2015d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) bubble_showing_ = true; 202a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) view_->Show(requests_, accept_states_, customization_mode_); 2035d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 2045d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)} 2055d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 2065d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void PermissionBubbleManager::FinalizeBubble() { 207a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) if (view_) 2085d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) view_->Hide(); 209a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) bubble_showing_ = false; 2105d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 2115d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) std::vector<PermissionBubbleRequest*>::iterator requests_iter; 2125d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) for (requests_iter = requests_.begin(); 2135d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) requests_iter != requests_.end(); 2145d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) requests_iter++) { 2155d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) (*requests_iter)->RequestFinished(); 2165d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 2175d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) requests_.clear(); 2185d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) accept_states_.clear(); 2195d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (queued_requests_.size()) { 2205d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) requests_ = queued_requests_; 2215d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) accept_states_.resize(requests_.size(), true); 2225d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) queued_requests_.clear(); 2235d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // TODO(leng): Explore other options of showing the next bubble. The 2245d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // advantage of this is that it uses the same code path as the first bubble. 2255d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) timer_->Reset(); 2265d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 2275d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)} 2285d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 2295d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void PermissionBubbleManager::SetCoalesceIntervalForTesting(int interval_ms) { 2305d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) timer_.reset(new base::Timer(FROM_HERE, 2315d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) base::TimeDelta::FromMilliseconds(interval_ms), 2325d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) base::Bind(&PermissionBubbleManager::ShowBubble, base::Unretained(this)), 2335d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) false)); 2345d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)} 235