blob: 56f28fdbf709d19d9375fc7b940ce7045245399b [file] [log] [blame]
// Copyright 2022 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_REQUEST_QUEUE_H_
#define COMPONENTS_PERMISSIONS_PERMISSION_REQUEST_QUEUE_H_
#include <cstddef>
#include <vector>
#include "base/containers/circular_deque.h"
#include "components/permissions/permission_request.h"
namespace permissions {
// Provides a container for holding pending PermissionRequest objects and
// provides access methods respecting the currently applicable feature flag
// configuration.
// The queue of permission requests is always held in the order of:
// High Priority Requests > Normal Priority Requests > Low Priority Requests.
// Using the |PushFront| and |PushBack| functions will push the new request in
// the front or back of the section of the queue that corresponds to that
// request's priority.
// High Priority Requests are requests that come from an Page-Embedded
// Permission Control.
// Low Priority Requests are requests for non-urgent permission types
// (notifications, geolocation) if the current platform supports the permission
// chip. If the permission chip is not supported, there are no low priority
// requests.
// Normal Priority Requests are all other requests.
class PermissionRequestQueue {
public:
using const_iterator =
std::vector<base::circular_deque<PermissionRequest*>>::const_iterator;
// Not copyable or movable
PermissionRequestQueue(const PermissionRequestQueue&) = delete;
PermissionRequestQueue& operator=(const PermissionRequestQueue&) = delete;
PermissionRequestQueue();
~PermissionRequestQueue();
bool IsEmpty() const;
size_t Count(PermissionRequest* request) const;
size_t size() const { return size_; }
// Push a new request into queue. This function will decide based on request
// priority and platform whether to call |PushBack| or |PushFront|.
void Push(permissions::PermissionRequest* request);
// Push a new request into the front of the section of the queue that
// corresponds to its priority. E.g.: calling this function on a normal
// priority |request| will put it in front of any other normal priority
// requests, but still behind any high priority requests.
void PushFront(permissions::PermissionRequest* request);
// Push a new request into the back of the section of the queue that
// corresponds to its priority. E.g.: calling this function on a normal
// priority |request| will put it behind any other normal priority requests,
// but still in front of any low priority requests.
void PushBack(permissions::PermissionRequest* request);
PermissionRequest* Pop();
PermissionRequest* Peek() const;
// Searches queued_requests_ and returns the first matching request, or
// nullptr if there is no match.
PermissionRequest* FindDuplicate(PermissionRequest* request) const;
const_iterator begin() const;
const_iterator end() const;
private:
enum class Priority {
kLow,
kMedium,
kHigh,
// Used to set the correct size of the |queued_requests_| vector.
kNum,
};
static Priority DetermineRequestPriority(
permissions::PermissionRequest* request);
void PushFrontInternal(permissions::PermissionRequest* request,
Priority priority);
void PushBackInternal(permissions::PermissionRequest* request,
Priority priority);
// Each priority has a separate deque. There is an assumption made that the
// priorities have strictly ascending, contignous values from lowest to
// highest.
std::vector<base::circular_deque<PermissionRequest*>> queued_requests_;
size_t size_{0};
};
} // namespace permissions
#endif // COMPONENTS_PERMISSIONS_PERMISSION_REQUEST_QUEUE_H_