blob: c515b19b689e7b09e772547300035457147ef160 [file] [log] [blame]
// Copyright 2014 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef COMPONENTS_PERMISSIONS_PERMISSION_PROMPT_H_
#define COMPONENTS_PERMISSIONS_PERMISSION_PROMPT_H_
#include <memory>
#include <optional>
#include <vector>
#include "base/functional/callback.h"
#include "base/memory/raw_ptr.h"
#include "components/permissions/features.h"
#include "components/permissions/permission_ui_selector.h"
#include "ui/gfx/geometry/rect.h"
#include "url/gurl.h"
namespace content {
class WebContents;
}
namespace ui {
class Event;
} // namespace ui
namespace permissions {
enum class PermissionPromptDisposition;
class PermissionRequest;
// This class is the platform-independent interface through which the permission
// request managers (which are one per tab) communicate to the UI surface.
// When the visible tab changes, the UI code must provide an object of this type
// to the manager for the visible tab.
class PermissionPrompt {
public:
// Permission prompt behavior on tab switching.
enum TabSwitchingBehavior {
// The prompt should be kept as-is on tab switching (usually because it's
// part of the containing tab so it will be hidden automatically when
// switching from said tab)
kKeepPromptAlive,
// Destroy the prompt but keep the permission request pending. When the user
// revisits the tab, the permission prompt is re-displayed.
kDestroyPromptButKeepRequestPending,
// Destroy the prompt and treat the permission request as being resolved
// with the PermissionAction::IGNORED result.
kDestroyPromptAndIgnoreRequest,
};
// The delegate will receive events caused by user action which need to
// be persisted in the per-tab UI state.
class Delegate {
public:
virtual ~Delegate() = default;
// These pointers should not be stored as the actual request objects may be
// deleted upon navigation and so on.
virtual const std::vector<std::unique_ptr<PermissionRequest>>&
Requests() = 0;
// Get the single origin for the current set of requests.
virtual GURL GetRequestingOrigin() const = 0;
// Get the top-level origin currently displayed in the address bar
// associated with the requests.
virtual GURL GetEmbeddingOrigin() const = 0;
virtual void Accept() = 0;
virtual void AcceptThisTime() = 0;
virtual void Deny() = 0;
virtual void Dismiss() = 0;
virtual void Ignore() = 0;
// Called to explicitly finalize the request, if
// |ShouldFinalizeRequestAfterDecided| returns false.
virtual void FinalizeCurrentRequests() = 0;
virtual void OpenHelpCenterLink(const ui::Event& event) = 0;
// This method preemptively ignores a permission request but does not
// finalize a permission prompt. That is needed in case a permission prompt
// is a quiet chip. This should be called only if an origin is subscribed to
// the `PermissionStatus.onchange` listener.
virtual void PreIgnoreQuietPrompt() = 0;
// If |ShouldCurrentRequestUseQuietUI| return true, this will provide a
// reason as to why the quiet UI needs to be used. Returns `std::nullopt`
// otherwise.
virtual std::optional<PermissionUiSelector::QuietUiReason>
ReasonForUsingQuietUi() const = 0;
// Notification permission requests might use a quiet UI when the
// "quiet-notification-prompts" feature is enabled. This is done either
// directly by the user in notifications settings, or via automatic logic
// that might trigger the current request to use the quiet UI.
virtual bool ShouldCurrentRequestUseQuietUI() const = 0;
// If the LocationBar is not visible, there is no place to display a quiet
// permission prompt. Abusive prompts will be ignored.
virtual bool ShouldDropCurrentRequestIfCannotShowQuietly() const = 0;
// Whether the current request has been shown to the user at least once.
virtual bool WasCurrentRequestAlreadyDisplayed() = 0;
// Set whether the current request should be dismissed if the current tab is
// closed.
virtual void SetDismissOnTabClose() = 0;
// Set whether the permission prompt bubble was shown for the current
// request.
virtual void SetPromptShown() = 0;
// Set when the user made any decision for the currentrequest.
virtual void SetDecisionTime() = 0;
// Set when the user made any decision for manage settings.
virtual void SetManageClicked() = 0;
// Set when the user made any decision for clicking on learn more link.
virtual void SetLearnMoreClicked() = 0;
// HaTS surveys may display at an inconvenient time, such as when a chip
// shown collapses after a certain timeout. To prevent affecting
// usability, this setter sets a callback that is be called when a HaTS
// survey is triggered to take appropriate actions.
virtual void SetHatsShownCallback(base::OnceCallback<void()> callback) = 0;
virtual content::WebContents* GetAssociatedWebContents() = 0;
virtual base::WeakPtr<Delegate> GetWeakPtr() = 0;
// Recreate the UI view because the UI flavor needs to change. Returns true
// iff successful.
virtual bool RecreateView() = 0;
virtual const PermissionPrompt* GetCurrentPrompt() const = 0;
};
typedef base::RepeatingCallback<
std::unique_ptr<PermissionPrompt>(content::WebContents*, Delegate*)>
Factory;
// Create and display a platform specific prompt.
static std::unique_ptr<PermissionPrompt> Create(
content::WebContents* web_contents,
Delegate* delegate);
virtual ~PermissionPrompt() = default;
// Updates where the prompt should be anchored. ex: fullscreen toggle.
// Returns true, if the update was successful, and false if the caller should
// recreate the view instead.
virtual bool UpdateAnchor() = 0;
// Get the behavior of this prompt when the user switches away from the
// associated tab.
virtual TabSwitchingBehavior GetTabSwitchingBehavior() = 0;
// Get the type of prompt UI shown for metrics.
virtual PermissionPromptDisposition GetPromptDisposition() const = 0;
// Check if the view shown is an "Ask" prompt for metrics. Currently this only
// distinguishes different prompt views displayed through the Page Embedded
// Permission Element.
virtual bool IsAskPrompt() const = 0;
// Get the prompt view bounds in screen coordinates.
virtual std::optional<gfx::Rect> GetViewBoundsInScreen() const = 0;
// Get whether the permission request is allowed to be finalized as soon a
// decision is transmitted. If this returns `false` the delegate should wait
// for an explicit |Delegate::FinalizeCurrentRequests()| call to be made.
virtual bool ShouldFinalizeRequestAfterDecided() const = 0;
// Return what variant of the secondary UI is shown for Page Embedded
// Permission Element.
virtual std::vector<permissions::ElementAnchoredBubbleVariant>
GetPromptVariants() const = 0;
virtual std::optional<feature_params::PermissionElementPromptPosition>
GetPromptPosition() const = 0;
};
} // namespace permissions
#endif // COMPONENTS_PERMISSIONS_PERMISSION_PROMPT_H_