Commit efad90f6 authored by gbillock@chromium.org's avatar gbillock@chromium.org

[WebsiteSettings] API for permissions bubbles.

This introduces a new API for clients to prepare permission bubbles
for display to the user. Currently Follows the API of the InfoBar system
pretty closely.

BUG=332115

Review URL: https://codereview.chromium.org/121113007

git-svn-id: svn://svn.chromium.org/chrome/trunk/src@245396 0039d316-1c4b-4281-b951-d872f2087c98
parent 9c0d9dfe
// Copyright 2014 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef CHROME_BROWSER_UI_WEBSITE_SETTINGS_PERMISSION_BUBBLE_DELEGATE_H_
#define CHROME_BROWSER_UI_WEBSITE_SETTINGS_PERMISSION_BUBBLE_DELEGATE_H_
#include "base/strings/string16.h"
// Describes the interface a feature utilizing permission bubbles should
// implement. A class of this type is registered with the permission bubble
// manager to receive updates about the result of the permissions request
// from the bubble. It should live until it is unregistered or until
// PermissionsBubbleDestroyed is called.
// Note that no particular guarantees are made about what exact UI surface
// is presented to the user. The delegate may be coalesced with other bubble
// requests, or depending on the situation, not shown at all.
class PermissionBubbleDelegate {
public:
virtual ~PermissionBubbleDelegate() {}
// Returns the resource ID of an associated icon. If kNoIconID is returned, no
// icon will be shown.
virtual int GetIconID() const = 0;
// Returns the prompt text for this permission. This is the central permission
// grant text, and must be phrased positively -- the permission bubble may
// coalesce different requests, and if it does, this text will be displayed
// next to a checkbox indicating the user grants the permission.
virtual base::string16 GetMessageText() const = 0;
// TODO(gbillock): Needed?
// Returns alternative text for the accept button in the case where this
// single permission request is triggered in the bubble.
// If the permission request is coalesced, the text will revert to the default
// "Accept"-alike, so the message text must be clear enough for users to
// understand even if this text is not used.
virtual base::string16 GetAlternateAcceptButtonText() const = 0;
// Called when the user has granted the requested permission.
virtual void PermissionGranted() = 0;
// Called when the user has denied the requested permission.
virtual void PermissionDenied() = 0;
// Called when the user has cancelled the permission request. This
// corresponds to a denial, but is segregated in case the context needs to
// be able to distinguish between an active refusal or an implicit refusal.
virtual void Cancelled() = 0;
// The bubble this delegate was associated with was answered by the user.
// It is safe for the delegate to be deleted at this point -- it will receive
// no further message from the permission bubble system. This method will
// eventually be called on every delegate which is not unregistered.
virtual void RequestFinished() = 0;
};
#endif // CHROME_BROWSER_UI_WEBSITE_SETTINGS_PERMISSION_BUBBLE_DELEGATE_H_
// Copyright 2014 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "chrome/browser/ui/website_settings/permission_bubble_manager.h"
#include "chrome/browser/ui/website_settings/permission_bubble_delegate.h"
DEFINE_WEB_CONTENTS_USER_DATA_KEY(PermissionBubbleManager);
void PermissionBubbleManager::AddPermissionBubbleDelegate(
PermissionBubbleDelegate* delegate) {
// Don't re-add existing delegate.
std::vector<PermissionBubbleDelegate*>::iterator di;
for (di = delegates_.begin(); di != delegates_.end(); di++) {
if (*di == delegate)
return;
}
delegates_.push_back(delegate);
// TODO(gbillock): do we need to make default state a delegate property?
accept_state_.push_back(false);
if (bubble_showing_ && view_)
view_->AddPermissionBubbleDelegate(delegate);
}
void PermissionBubbleManager::RemovePermissionBubbleDelegate(
PermissionBubbleDelegate* delegate) {
std::vector<PermissionBubbleDelegate*>::iterator di;
std::vector<bool>::iterator ai;
for (di = delegates_.begin(), ai = accept_state_.begin();
di != delegates_.end(); di++, ai++) {
if (*di == delegate) {
if (bubble_showing_ && view_)
view_->RemovePermissionBubbleDelegate(delegate);
delegates_.erase(di);
accept_state_.erase(ai);
return;
}
}
}
void PermissionBubbleManager::SetView(PermissionBubbleView* view) {
view_ = view;
if (view_ == NULL)
return;
if (bubble_showing_) {
view_->Show(delegates_, accept_state_);
} else {
view_->Hide();
return;
}
}
PermissionBubbleManager::PermissionBubbleManager(
content::WebContents* web_contents)
: content::WebContentsObserver(web_contents),
bubble_showing_(false),
view_(NULL) {
}
PermissionBubbleManager::~PermissionBubbleManager() {}
void PermissionBubbleManager::WebContentsDestroyed(
content::WebContents* web_contents) {
// Synthetic cancel event if the user closes the WebContents.
Closing();
// The WebContents is going away; be aggressively paranoid and delete
// ourselves lest other parts of the system attempt to add permission bubbles
// or use us otherwise during the destruction.
web_contents->RemoveUserData(UserDataKey());
// That was the equivalent of "delete this". This object is now destroyed;
// returning from this function is the only safe thing to do.
}
void PermissionBubbleManager::ToggleAccept(int delegate_index, bool new_value) {
DCHECK(delegate_index < static_cast<int>(accept_state_.size()));
accept_state_[delegate_index] = new_value;
}
void PermissionBubbleManager::Accept() {
std::vector<PermissionBubbleDelegate*>::iterator di;
std::vector<bool>::iterator ai;
for (di = delegates_.begin(), ai = accept_state_.begin();
di != delegates_.end(); di++, ai++) {
if (*ai)
(*di)->PermissionGranted();
else
(*di)->PermissionDenied();
}
FinalizeBubble();
}
void PermissionBubbleManager::Deny() {
std::vector<PermissionBubbleDelegate*>::iterator di;
for (di = delegates_.begin(); di != delegates_.end(); di++)
(*di)->PermissionDenied();
FinalizeBubble();
}
void PermissionBubbleManager::Closing() {
std::vector<PermissionBubbleDelegate*>::iterator di;
for (di = delegates_.begin(); di != delegates_.end(); di++)
(*di)->Cancelled();
FinalizeBubble();
}
void PermissionBubbleManager::FinalizeBubble() {
std::vector<PermissionBubbleDelegate*>::iterator di;
for (di = delegates_.begin(); di != delegates_.end(); di++)
(*di)->RequestFinished();
delegates_.clear();
accept_state_.clear();
}
// Copyright 2014 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef CHROME_BROWSER_UI_WEBSITE_SETTINGS_PERMISSION_BUBBLE_MANAGER_H_
#define CHROME_BROWSER_UI_WEBSITE_SETTINGS_PERMISSION_BUBBLE_MANAGER_H_
#include <vector>
#include "chrome/browser/ui/website_settings/permission_bubble_view.h"
#include "content/public/browser/web_contents_observer.h"
#include "content/public/browser/web_contents_user_data.h"
class PermissionBubbleDelegate;
// Provides access to permissions bubbles. Allows clients to add a delegate
// callback interface to the existing permission bubble configuration.
// Depending on the situation and policy, that may add new UI to an existing
// permission bubble, create and show a new permission bubble, or provide no
// visible UI action at all. (In that case, the delegate will be immediately
// informed that the permission request failed.)
//
// A PermissionBubbleManager is associated with a particular WebContents.
// Delegates attached to a particular WebContents' PBM must outlive it.
//
// The PermissionBubbleManager should be addressed on the UI thread.
class PermissionBubbleManager
: public content::WebContentsObserver,
public content::WebContentsUserData<PermissionBubbleManager>,
public PermissionBubbleView::Delegate {
public:
virtual ~PermissionBubbleManager();
// Add a new consumer delegate to the permission bubble. Ownership of the
// delegate remains with the caller. The caller must arrange for the delegate
// to outlive the PermissionBubbleManager.
virtual void AddPermissionBubbleDelegate(PermissionBubbleDelegate* delegate);
// Remove a consumer delegate from the permission bubble.
virtual void RemovePermissionBubbleDelegate(
PermissionBubbleDelegate* delegate);
// Set the active view for the permission bubble. If this is NULL, it
// means the permission bubble is no longer showing.
virtual void SetView(PermissionBubbleView* view);
private:
friend class content::WebContentsUserData<PermissionBubbleManager>;
explicit PermissionBubbleManager(content::WebContents* web_contents);
// contents::WebContentsObserver:
virtual void WebContentsDestroyed(
content::WebContents* web_contents) OVERRIDE;
// PermissionBubbleView::Delegate:
virtual void ToggleAccept(int delegate_index, bool new_value) OVERRIDE;
virtual void Accept() OVERRIDE;
virtual void Deny() OVERRIDE;
virtual void Closing() OVERRIDE;
// Finalize the pending permissions request.
void FinalizeBubble();
// Whether or not we are showing the bubble in this tab.
bool bubble_showing_;
// Set to the UI surface to be used to display the permissions requests.
PermissionBubbleView* view_;
std::vector<PermissionBubbleDelegate*> delegates_;
std::vector<bool> accept_state_;
};
#endif // CHROME_BROWSER_UI_WEBSITE_SETTINGS_PERMISSION_BUBBLE_MANAGER_H_
// Copyright 2014 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef CHROME_BROWSER_UI_WEBSITE_SETTINGS_PERMISSION_BUBBLE_VIEW_H_
#define CHROME_BROWSER_UI_WEBSITE_SETTINGS_PERMISSION_BUBBLE_VIEW_H_
#include <vector>
class PermissionBubbleDelegate;
class PermissionBubbleManager;
// This class is the platform-independent base class which the
// manager uses to communicate to the UI surface. The UI toolkit
// must set the manager to the view for each tab change caused
// in the window.
class PermissionBubbleView {
public:
class Delegate {
virtual void ToggleAccept(int index, bool new_value) = 0;
virtual void Accept() = 0;
virtual void Deny() = 0;
virtual void Closing() = 0;
};
// Set the delegate which will receive UI events forwarded from the bubble.
virtual void SetDelegate(Delegate* delegate) = 0;
// Used for live updates to the bubble.
virtual void AddPermissionBubbleDelegate(
PermissionBubbleDelegate* delegate) = 0;
virtual void RemovePermissionBubbleDelegate(
PermissionBubbleDelegate* delegate) = 0;
virtual void Show(
const std::vector<PermissionBubbleDelegate*>& delegates,
const std::vector<bool>& accept_state) = 0;
virtual void Hide() = 0;
};
#endif // CHROME_BROWSER_UI_WEBSITE_SETTINGS_PERMISSION_BUBBLE_VIEW_H_
......@@ -2156,6 +2156,10 @@
'browser/ui/views/website_settings/website_settings_popup_view.h',
'browser/ui/web_applications/web_app_ui.cc',
'browser/ui/web_applications/web_app_ui.h',
'browser/ui/website_settings/permission_bubble_delegate.h',
'browser/ui/website_settings/permission_bubble_manager.cc',
'browser/ui/website_settings/permission_bubble_manager.h',
'browser/ui/website_settings/permission_bubble_view.h',
'browser/ui/website_settings/permission_menu_model.cc',
'browser/ui/website_settings/permission_menu_model.h',
'browser/ui/website_settings/website_settings.cc',
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment