aad9e6e843f7205776645ba3a780f725dbbb5a7a
[WebKit.git] / Source / WebKit2 / 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 <wtf/MonotonicTime.h>
31 #include <wtf/RunLoop.h>
32 #include <wtf/Vector.h>
33 #include <wtf/WallTime.h>
34 #include <wtf/text/WTFString.h>
35
36 #if HAVE(CORE_PREDICTION)
37 #include "ResourceLoadStatisticsClassifierCocoa.h"
38 #endif
39
40 namespace WTF {
41 class WorkQueue;
42 }
43
44 namespace WebCore {
45 class FileMonitor;
46 class KeyedDecoder;
47 class KeyedEncoder;
48 class URL;
49 struct ResourceLoadStatistics;
50 }
51
52 namespace WebKit {
53
54 class WebProcessProxy;
55
56 enum class ShouldClearFirst;
57
58 // FIXME: We should consider moving FileSystem I/O to a separate class.
59 class WebResourceLoadStatisticsStore final : public IPC::Connection::WorkQueueMessageReceiver {
60 public:
61     using UpdateCookiePartitioningForDomainsHandler = WTF::Function<void(const Vector<String>& domainsToRemove, const Vector<String>& domainsToAdd, ShouldClearFirst)>;
62     static Ref<WebResourceLoadStatisticsStore> create(const String& resourceLoadStatisticsDirectory, UpdateCookiePartitioningForDomainsHandler&& updateCookiePartitioningForDomainsHandler = { })
63     {
64         return adoptRef(*new WebResourceLoadStatisticsStore(resourceLoadStatisticsDirectory, WTFMove(updateCookiePartitioningForDomainsHandler)));
65     }
66
67     ~WebResourceLoadStatisticsStore();
68
69     void setNotifyPagesWhenDataRecordsWereScanned(bool value) { m_parameters.shouldNotifyPagesWhenDataRecordsWereScanned = value; }
70     void setShouldClassifyResourcesBeforeDataRecordsRemoval(bool value) { m_parameters.shouldClassifyResourcesBeforeDataRecordsRemoval = value; }
71     void setShouldSubmitTelemetry(bool value) { m_parameters.shouldSubmitTelemetry = value; }
72
73     void resourceLoadStatisticsUpdated(Vector<WebCore::ResourceLoadStatistics>&& origins);
74
75     void processWillOpenConnection(WebProcessProxy&, IPC::Connection&);
76     void processDidCloseConnection(WebProcessProxy&, IPC::Connection&);
77     void applicationWillTerminate();
78
79     void logUserInteraction(const WebCore::URL&);
80     void clearUserInteraction(const WebCore::URL&);
81     void hasHadUserInteraction(const WebCore::URL&, WTF::Function<void (bool)>&&);
82     void setLastSeen(const WebCore::URL&, Seconds);
83     void setPrevalentResource(const WebCore::URL&);
84     void isPrevalentResource(const WebCore::URL&, WTF::Function<void (bool)>&&);
85     void clearPrevalentResource(const WebCore::URL&);
86     void setGrandfathered(const WebCore::URL&, bool);
87     void isGrandfathered(const WebCore::URL&, WTF::Function<void (bool)>&&);
88     void setSubframeUnderTopFrameOrigin(const WebCore::URL& subframe, const WebCore::URL& topFrame);
89     void setSubresourceUnderTopFrameOrigin(const WebCore::URL& subresource, const WebCore::URL& topFrame);
90     void setSubresourceUniqueRedirectTo(const WebCore::URL& subresource, const WebCore::URL& hostNameRedirectedTo);
91     void scheduleCookiePartitioningUpdate();
92     void scheduleCookiePartitioningUpdateForDomains(const Vector<String>& domainsToRemove, const Vector<String>& domainsToAdd, ShouldClearFirst);
93     void processStatisticsAndDataRecords();
94     void submitTelemetry();
95     void scheduleCookiePartitioningStateReset();
96
97     void scheduleClearInMemory();
98     void scheduleClearInMemoryAndPersistent();
99     void scheduleClearInMemoryAndPersistent(std::chrono::system_clock::time_point modifiedSince);
100
101     void setTimeToLiveUserInteraction(Seconds);
102     void setTimeToLiveCookiePartitionFree(Seconds);
103     void setMinimumTimeBetweenDataRecordsRemoval(Seconds);
104     void setGrandfatheringTime(Seconds);
105     void setMaxStatisticsEntries(size_t);
106     void setPruneEntriesDownTo(size_t);
107     
108     void processStatistics(const WTF::Function<void (const WebCore::ResourceLoadStatistics&)>&) const;
109     void pruneStatisticsIfNeeded();
110
111     void resetParametersToDefaultValues();
112     
113 private:
114     WebResourceLoadStatisticsStore(const String&, UpdateCookiePartitioningForDomainsHandler&&);
115
116     void readDataFromDiskIfNeeded();
117
118     void removeDataRecords();
119     void startMonitoringStatisticsStorage();
120     void stopMonitoringStatisticsStorage();
121
122     String statisticsStoragePath() const;
123     String resourceLogFilePath() const;
124
125     // IPC::MessageReceiver
126     void didReceiveMessage(IPC::Connection&, IPC::Decoder&) override;
127
128     void grandfatherExistingWebsiteData();
129
130     void writeStoreToDisk();
131     void scheduleOrWriteStoreToDisk();
132     std::unique_ptr<WebCore::KeyedDecoder> createDecoderFromDisk(const String& path) const;
133     WallTime statisticsFileModificationTime(const String& label) const;
134     void platformExcludeFromBackup() const;
135     void deleteStoreFromDisk();
136     void syncWithExistingStatisticsStorageIfNeeded();
137     void refreshFromDisk();
138     bool hasStatisticsFileChangedSinceLastSync(const String& path) const;
139     void performDailyTasks();
140     bool shouldRemoveDataRecords() const;
141     void setDataRecordsBeingRemoved(bool);
142
143     bool shouldPartitionCookies(const WebCore::ResourceLoadStatistics&) const;
144     bool hasStatisticsExpired(const WebCore::ResourceLoadStatistics&) const;
145     bool hasHadUnexpiredRecentUserInteraction(WebCore::ResourceLoadStatistics&) const;
146     void includeTodayAsOperatingDateIfNecessary();
147     Vector<String> topPrivatelyControlledDomainsToRemoveWebsiteDataFor();
148     void updateCookiePartitioning();
149     void updateCookiePartitioningForDomains(const Vector<String>& domainsToRemove, const Vector<String>& domainsToAdd, ShouldClearFirst);
150     void mergeStatistics(Vector<WebCore::ResourceLoadStatistics>&&);
151     WebCore::ResourceLoadStatistics& ensureResourceStatisticsForPrimaryDomain(const String&);
152     std::unique_ptr<WebCore::KeyedEncoder> createEncoderFromData() const;
153     void populateFromDecoder(WebCore::KeyedDecoder&);
154     void clearInMemory();
155
156     void resetCookiePartitioningState();
157
158 #if PLATFORM(COCOA)
159     void registerUserDefaultsIfNeeded();
160 #endif
161
162     struct Parameters {
163         size_t pruneEntriesDownTo { 800 };
164         size_t maxStatisticsEntries { 1000 };
165         std::optional<Seconds> timeToLiveUserInteraction;
166         Seconds timeToLiveCookiePartitionFree { 24_h };
167         Seconds minimumTimeBetweenDataRecordsRemoval { 1_h };
168         Seconds grandfatheringTime { 1_h };
169         bool shouldNotifyPagesWhenDataRecordsWereScanned { false };
170         bool shouldClassifyResourcesBeforeDataRecordsRemoval { true };
171         bool shouldSubmitTelemetry { true };
172     };
173
174     HashMap<String, WebCore::ResourceLoadStatistics> m_resourceStatisticsMap;
175 #if HAVE(CORE_PREDICTION)
176     ResourceLoadStatisticsClassifierCocoa m_resourceLoadStatisticsClassifier;
177 #else
178     ResourceLoadStatisticsClassifier m_resourceLoadStatisticsClassifier;
179 #endif
180     Ref<WTF::WorkQueue> m_statisticsQueue;
181     std::unique_ptr<WebCore::FileMonitor> m_statisticsStorageMonitor;
182     Deque<WTF::WallTime> m_operatingDates;
183
184     UpdateCookiePartitioningForDomainsHandler m_updateCookiePartitioningForDomainsHandler;
185
186     WallTime m_endOfGrandfatheringTimestamp;
187     const String m_statisticsStoragePath;
188     WallTime m_lastStatisticsFileSyncTime;
189     MonotonicTime m_lastStatisticsWriteTime;
190     RunLoop::Timer<WebResourceLoadStatisticsStore> m_dailyTasksTimer;
191     MonotonicTime m_lastTimeDataRecordsWereRemoved;
192
193     Parameters m_parameters;
194
195     bool m_dataRecordsBeingRemoved { false };
196     bool m_didScheduleWrite { false };
197 };
198
199 } // namespace WebKit