Storage Access API: Make document.hasStorageAccess() retrieve current status from...
[WebKit-https.git] / Source / WebKit / UIProcess / WebResourceLoadStatisticsStore.h
1 /*
2  * Copyright (C) 2016-2017 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. AND ITS CONTRIBUTORS ``AS IS''
14  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
15  * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
16  * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
17  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
18  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
19  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
20  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
21  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
22  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
23  * THE POSSIBILITY OF SUCH DAMAGE.
24  */
25
26 #pragma once
27
28 #include "Connection.h"
29 #include "ResourceLoadStatisticsClassifier.h"
30 #include "ResourceLoadStatisticsPersistentStorage.h"
31 #include "WebsiteDataType.h"
32 #include <wtf/CompletionHandler.h>
33 #include <wtf/HashSet.h>
34 #include <wtf/MonotonicTime.h>
35 #include <wtf/RunLoop.h>
36 #include <wtf/Vector.h>
37 #include <wtf/WallTime.h>
38 #include <wtf/text/WTFString.h>
39
40 #if HAVE(CORE_PREDICTION)
41 #include "ResourceLoadStatisticsClassifierCocoa.h"
42 #endif
43
44 namespace WTF {
45 class WorkQueue;
46 }
47
48 namespace WebCore {
49 class KeyedDecoder;
50 class KeyedEncoder;
51 class URL;
52 struct ResourceLoadStatistics;
53 }
54
55 namespace WebKit {
56
57 class OperatingDate;
58 class WebProcessProxy;
59
60 enum class ShouldClearFirst;
61
62 class WebResourceLoadStatisticsStore final : public IPC::Connection::WorkQueueMessageReceiver {
63 public:
64     using UpdatePrevalentDomainsToPartitionOrBlockCookiesHandler = WTF::Function<void(const Vector<String>& domainsToPartition, const Vector<String>& domainsToBlock, const Vector<String>& domainsToNeitherPartitionNorBlock, ShouldClearFirst)>;
65     using HasStorageAccessForPrevalentDomainsHandler = WTF::Function<void(const String& resourceDomain, const String& firstPartyDomain, uint64_t frameID, uint64_t pageID, WTF::Function<void(bool hasAccess)>&& callback)>;
66     using UpdateStorageAccessForPrevalentDomainsHandler = WTF::Function<void(const String& resourceDomain, const String& firstPartyDomain, uint64_t frameID, uint64_t pageID, bool value, WTF::Function<void(bool wasGranted)>&& callback)>;
67     using RemovePrevalentDomainsHandler = WTF::Function<void (const Vector<String>&)>;
68     static Ref<WebResourceLoadStatisticsStore> create(const String& resourceLoadStatisticsDirectory, Function<void (const String&)>&& testingCallback, UpdatePrevalentDomainsToPartitionOrBlockCookiesHandler&& updatePrevalentDomainsToPartitionOrBlockCookiesHandler = [](const Vector<String>&, const Vector<String>&, const Vector<String>&, ShouldClearFirst) { }, HasStorageAccessForPrevalentDomainsHandler&& hasStorageAccessForPrevalentDomainsHandler = [](const String&, const String&, uint64_t, uint64_t, WTF::Function<void(bool)>&&) { }, UpdateStorageAccessForPrevalentDomainsHandler&& updateStorageAccessForPrevalentDomainsHandler = [](const String&, const String&, uint64_t, uint64_t, bool, WTF::Function<void(bool)>&&) { }, RemovePrevalentDomainsHandler&& removeDomainsHandler = [] (const Vector<String>&) { })
69     {
70         return adoptRef(*new WebResourceLoadStatisticsStore(resourceLoadStatisticsDirectory, WTFMove(testingCallback), WTFMove(updatePrevalentDomainsToPartitionOrBlockCookiesHandler), WTFMove(hasStorageAccessForPrevalentDomainsHandler), WTFMove(updateStorageAccessForPrevalentDomainsHandler), WTFMove(removeDomainsHandler)));
71     }
72
73     ~WebResourceLoadStatisticsStore();
74
75     static const OptionSet<WebsiteDataType>& monitoredDataTypes();
76
77     bool isEmpty() const { return m_resourceStatisticsMap.isEmpty(); }
78     WorkQueue& statisticsQueue() { return m_statisticsQueue.get(); }
79
80     void setNotifyPagesWhenDataRecordsWereScanned(bool value) { m_parameters.shouldNotifyPagesWhenDataRecordsWereScanned = value; }
81     void setShouldClassifyResourcesBeforeDataRecordsRemoval(bool value) { m_parameters.shouldClassifyResourcesBeforeDataRecordsRemoval = value; }
82     void setShouldSubmitTelemetry(bool value) { m_parameters.shouldSubmitTelemetry = value; }
83
84     void resourceLoadStatisticsUpdated(Vector<WebCore::ResourceLoadStatistics>&& origins);
85
86     void hasStorageAccess(String&& subFrameHost, String&& topFrameHost, uint64_t frameID, uint64_t pageID, WTF::CompletionHandler<void (bool)>&& callback);
87     void requestStorageAccess(String&& subFrameHost, String&& topFrameHost, uint64_t frameID, uint64_t pageID, WTF::CompletionHandler<void (bool)>&& callback);
88     void requestStorageAccessCallback(bool wasGranted, uint64_t contextId);
89
90     void processWillOpenConnection(WebProcessProxy&, IPC::Connection&);
91     void processDidCloseConnection(WebProcessProxy&, IPC::Connection&);
92     void applicationWillTerminate();
93
94     void logUserInteraction(const WebCore::URL&);
95     void logNonRecentUserInteraction(const WebCore::URL&);
96     void clearUserInteraction(const WebCore::URL&);
97     void hasHadUserInteraction(const WebCore::URL&, WTF::Function<void (bool)>&&);
98     void setLastSeen(const WebCore::URL&, Seconds);
99     void setPrevalentResource(const WebCore::URL&);
100     void isPrevalentResource(const WebCore::URL&, WTF::Function<void (bool)>&&);
101     void isRegisteredAsSubFrameUnder(const WebCore::URL& subFrame, const WebCore::URL& topFrame, WTF::Function<void (bool)>&&);
102     void isRegisteredAsRedirectingTo(const WebCore::URL& hostRedirectedFrom, const WebCore::URL& hostRedirectedTo, WTF::Function<void (bool)>&&);
103     void clearPrevalentResource(const WebCore::URL&);
104     void setGrandfathered(const WebCore::URL&, bool);
105     void isGrandfathered(const WebCore::URL&, WTF::Function<void (bool)>&&);
106     void setSubframeUnderTopFrameOrigin(const WebCore::URL& subframe, const WebCore::URL& topFrame);
107     void setSubresourceUnderTopFrameOrigin(const WebCore::URL& subresource, const WebCore::URL& topFrame);
108     void setSubresourceUniqueRedirectTo(const WebCore::URL& subresource, const WebCore::URL& hostNameRedirectedTo);
109     void scheduleCookiePartitioningUpdate();
110     void scheduleCookiePartitioningUpdateForDomains(const Vector<String>& domainsToPartition, const Vector<String>& domainsToBlock, const Vector<String>& domainsToNeitherPartitionNorBlock, ShouldClearFirst);
111     void scheduleClearPartitioningStateForDomains(const Vector<String>& domains);
112     void scheduleStatisticsAndDataRecordsProcessing();
113     void submitTelemetry();
114     void scheduleCookiePartitioningStateReset();
115
116     void scheduleClearInMemory();
117     
118     enum class ShouldGrandfather {
119         No,
120         Yes,
121     };
122     void scheduleClearInMemoryAndPersistent(ShouldGrandfather);
123     void scheduleClearInMemoryAndPersistent(std::chrono::system_clock::time_point modifiedSince, ShouldGrandfather);
124
125     void setTimeToLiveUserInteraction(Seconds);
126     void setTimeToLiveCookiePartitionFree(Seconds);
127     void setMinimumTimeBetweenDataRecordsRemoval(Seconds);
128     void setGrandfatheringTime(Seconds);
129     void setMaxStatisticsEntries(size_t);
130     void setPruneEntriesDownTo(size_t);
131     
132     void processStatistics(const WTF::Function<void (const WebCore::ResourceLoadStatistics&)>&) const;
133     void pruneStatisticsIfNeeded();
134
135     void resetParametersToDefaultValues();
136
137     std::unique_ptr<WebCore::KeyedEncoder> createEncoderFromData() const;
138     void mergeWithDataFromDecoder(WebCore::KeyedDecoder&);
139     void clearInMemory();
140     void grandfatherExistingWebsiteData();
141
142     void setStatisticsTestingCallback(Function<void (const String&)>&& callback) { m_statisticsTestingCallback = WTFMove(callback); }
143     void logTestingEvent(const String&);
144
145 private:
146     WebResourceLoadStatisticsStore(const String&, Function<void(const String&)>&& testingCallback, UpdatePrevalentDomainsToPartitionOrBlockCookiesHandler&&, HasStorageAccessForPrevalentDomainsHandler&&, UpdateStorageAccessForPrevalentDomainsHandler&&, RemovePrevalentDomainsHandler&&);
147
148     void removeDataRecords();
149
150     // IPC::MessageReceiver
151     void didReceiveMessage(IPC::Connection&, IPC::Decoder&) override;
152
153     void performDailyTasks();
154     bool shouldRemoveDataRecords() const;
155     void setDataRecordsBeingRemoved(bool);
156
157     bool shouldPartitionCookies(const WebCore::ResourceLoadStatistics&) const;
158     bool shouldBlockCookies(const WebCore::ResourceLoadStatistics&) const;
159     bool hasStatisticsExpired(const WebCore::ResourceLoadStatistics&) const;
160     bool hasHadUnexpiredRecentUserInteraction(WebCore::ResourceLoadStatistics&) const;
161     void includeTodayAsOperatingDateIfNecessary();
162     Vector<String> topPrivatelyControlledDomainsToRemoveWebsiteDataFor();
163     void updateCookiePartitioning();
164     void updateCookiePartitioningForDomains(const Vector<String>& domainsToPartition, const Vector<String>& domainsToBlock, const Vector<String>& domainsToNeitherPartitionNorBlock, ShouldClearFirst);
165     void clearPartitioningStateForDomains(const Vector<String>& domains);
166     void mergeStatistics(Vector<WebCore::ResourceLoadStatistics>&&);
167     WebCore::ResourceLoadStatistics& ensureResourceStatisticsForPrimaryDomain(const String&);
168     void processStatisticsAndDataRecords();
169
170     void resetCookiePartitioningState();
171
172 #if PLATFORM(COCOA)
173     void registerUserDefaultsIfNeeded();
174 #endif
175
176     struct Parameters {
177         size_t pruneEntriesDownTo { 800 };
178         size_t maxStatisticsEntries { 1000 };
179         std::optional<Seconds> timeToLiveUserInteraction;
180         Seconds timeToLiveCookiePartitionFree { 24_h };
181         Seconds minimumTimeBetweenDataRecordsRemoval { 1_h };
182         Seconds grandfatheringTime { 24_h * 7 };
183         bool shouldNotifyPagesWhenDataRecordsWereScanned { false };
184         bool shouldClassifyResourcesBeforeDataRecordsRemoval { true };
185         bool shouldSubmitTelemetry { true };
186     };
187
188     HashMap<String, WebCore::ResourceLoadStatistics> m_resourceStatisticsMap;
189 #if HAVE(CORE_PREDICTION)
190     ResourceLoadStatisticsClassifierCocoa m_resourceLoadStatisticsClassifier;
191 #else
192     ResourceLoadStatisticsClassifier m_resourceLoadStatisticsClassifier;
193 #endif
194     Ref<WTF::WorkQueue> m_statisticsQueue;
195     ResourceLoadStatisticsPersistentStorage m_persistentStorage;
196     Vector<OperatingDate> m_operatingDates;
197
198     UpdatePrevalentDomainsToPartitionOrBlockCookiesHandler m_updatePrevalentDomainsToPartitionOrBlockCookiesHandler;
199     HasStorageAccessForPrevalentDomainsHandler m_hasStorageAccessForPrevalentDomainsHandler;
200     UpdateStorageAccessForPrevalentDomainsHandler m_updateStorageAccessForPrevalentDomainsHandler;
201     RemovePrevalentDomainsHandler m_removeDomainsHandler;
202
203     WallTime m_endOfGrandfatheringTimestamp;
204     RunLoop::Timer<WebResourceLoadStatisticsStore> m_dailyTasksTimer;
205     MonotonicTime m_lastTimeDataRecordsWereRemoved;
206
207     Parameters m_parameters;
208
209 #if ENABLE(NETSCAPE_PLUGIN_API)
210     HashSet<uint64_t> m_activePluginTokens;
211 #endif
212     bool m_dataRecordsBeingRemoved { false };
213
214     Function<void (const String&)> m_statisticsTestingCallback;
215 };
216
217 } // namespace WebKit