1/*
2 * Copyright (C) 2019 Apple Inc. All Rights Reserved.
3 *
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions
6 * are met:
7 * 1. Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * 2. Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 *
13 * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
14 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
15 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
16 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
17 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
18 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
19 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
20 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
21 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
22 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
23 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
24 */
25
26#pragma once
27
28#include "ClientOrigin.h"
29#include <wtf/CompletionHandler.h>
30#include <wtf/Deque.h>
31#include <wtf/HashMap.h>
32#include <wtf/HashSet.h>
33#include <wtf/WeakPtr.h>
34
35namespace WebCore {
36
37class StorageQuotaUser;
38
39class StorageQuotaManager : public CanMakeWeakPtr<StorageQuotaManager> {
40 WTF_MAKE_FAST_ALLOCATED;
41public:
42 using SpaceIncreaseRequester = WTF::Function<void(uint64_t quota, uint64_t currentSpace, uint64_t spaceIncrease, CompletionHandler<void(Optional<uint64_t>)>&&)>;
43 StorageQuotaManager(uint64_t quota, SpaceIncreaseRequester&& spaceIncreaseRequester)
44 : m_quota(quota)
45 , m_spaceIncreaseRequester(WTFMove(spaceIncreaseRequester))
46 {
47 }
48 WEBCORE_EXPORT ~StorageQuotaManager();
49
50 static constexpr uint64_t defaultThirdPartyQuotaFromPerOriginQuota(uint64_t quota) { return quota / 10; }
51
52 static constexpr uint64_t defaultQuota() { return 1000 * MB; }
53 static constexpr uint64_t defaultThirdPartyQuota() { return defaultThirdPartyQuotaFromPerOriginQuota(defaultQuota()); }
54
55 WEBCORE_EXPORT void addUser(StorageQuotaUser&);
56 WEBCORE_EXPORT void removeUser(StorageQuotaUser&);
57
58 enum class Decision { Deny, Grant };
59 using RequestCallback = CompletionHandler<void(Decision)>;
60 WEBCORE_EXPORT void requestSpace(uint64_t, RequestCallback&&);
61 void resetQuota(uint64_t newQuota) { m_quota = newQuota; }
62
63 WEBCORE_EXPORT void updateQuotaBasedOnSpaceUsage();
64
65private:
66 uint64_t spaceUsage() const;
67 bool shouldAskForMoreSpace(uint64_t spaceIncrease) const;
68 void askForMoreSpace(uint64_t spaceIncrease);
69
70 void initializeUsersIfNeeded();
71 void askUserToInitialize(StorageQuotaUser&);
72
73 enum class ShouldDequeueFirstPendingRequest { No, Yes };
74 void processPendingRequests(Optional<uint64_t>, ShouldDequeueFirstPendingRequest);
75
76 uint64_t m_quota { 0 };
77
78 bool m_isWaitingForSpaceIncreaseResponse { false };
79 SpaceIncreaseRequester m_spaceIncreaseRequester;
80
81 enum class WhenInitializedCalled { No, Yes };
82 HashMap<StorageQuotaUser*, WhenInitializedCalled> m_pendingInitializationUsers;
83 HashSet<const StorageQuotaUser*> m_users;
84
85 struct PendingRequest {
86 uint64_t spaceIncrease;
87 RequestCallback callback;
88 };
89 Deque<PendingRequest> m_pendingRequests;
90};
91
92} // namespace WebCore
93