#define COMPONENTS_PERMISSIONS_PERMISSION_REQUEST_QUEUE_H_
#include <cstddef>
+#include <vector>
#include "base/containers/circular_deque.h"
#include "components/permissions/permission_request.h"
// 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 =
- base::circular_deque<PermissionRequest*>::const_iterator;
- using const_reverse_iterator =
- base::circular_deque<PermissionRequest*>::const_reverse_iterator;
+ std::vector<base::circular_deque<PermissionRequest*>>::const_iterator;
// Not copyable or movable
PermissionRequestQueue(const PermissionRequestQueue&) = delete;
~PermissionRequestQueue();
bool IsEmpty() const;
- size_t Count() 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);
- // Push a new request into queue. When |reorder_based_on_priority| is set, the
- // request might be inserted to correct position based on its priority,
- // instead of be pushed to the front of queue.
- void Push(permissions::PermissionRequest* request,
- bool reorder_based_on_priority = false);
PermissionRequest* Pop();
PermissionRequest* Peek() const;
// nullptr if there is no match.
PermissionRequest* FindDuplicate(PermissionRequest* request) const;
- // Used for iterating over the queued requests.
const_iterator begin() const;
const_iterator end() const;
private:
- void PushInternal(permissions::PermissionRequest* request);
+ 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_;
- base::circular_deque<PermissionRequest*> queued_requests_;
+ size_t size_{0};
};
} // namespace permissions