Unreviewed, fix iOS build with recent SDKs.
[WebKit-https.git] / Source / WebKit / UIProcess / API / Cocoa / WKContentRuleListStore.mm
1 /*
2  * Copyright (C) 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 #import "config.h"
27 #import "WKContentRuleListInternal.h"
28 #import "WKContentRuleListStoreInternal.h"
29
30 #import "APIContentRuleListStore.h"
31 #import "NetworkCacheFilesystem.h"
32 #import "WKErrorInternal.h"
33 #import <wtf/BlockPtr.h>
34 #import <wtf/CompletionHandler.h>
35
36 static WKErrorCode toWKErrorCode(const std::error_code& error)
37 {
38     ASSERT(error.category() == API::contentRuleListStoreErrorCategory());
39     switch (static_cast<API::ContentRuleListStore::Error>(error.value())) {
40     case API::ContentRuleListStore::Error::LookupFailed:
41         return WKErrorContentRuleListStoreLookUpFailed;
42     case API::ContentRuleListStore::Error::VersionMismatch:
43         return WKErrorContentRuleListStoreVersionMismatch;
44     case API::ContentRuleListStore::Error::CompileFailed:
45         return WKErrorContentRuleListStoreCompileFailed;
46     case API::ContentRuleListStore::Error::RemoveFailed:
47         return WKErrorContentRuleListStoreRemoveFailed;
48     }
49     ASSERT_NOT_REACHED();
50     return WKErrorUnknown;
51 }
52
53 @implementation WKContentRuleListStore
54
55 - (void)dealloc
56 {
57     _contentRuleListStore->~ContentRuleListStore();
58
59     [super dealloc];
60 }
61
62 + (instancetype)defaultStore
63 {
64     const bool legacyFilename = false;
65     return wrapper(API::ContentRuleListStore::defaultStore(legacyFilename));
66 }
67
68 + (instancetype)storeWithURL:(NSURL *)url
69 {
70     const bool legacyFilename = false;
71     return wrapper(API::ContentRuleListStore::storeWithPath(url.absoluteURL.fileSystemRepresentation, legacyFilename));
72 }
73
74 - (void)compileContentRuleListForIdentifier:(NSString *)identifier encodedContentRuleList:(NSString *)encodedContentRuleList completionHandler:(void (^)(WKContentRuleList *, NSError *))completionHandler
75 {
76     [self _compileContentRuleListForIdentifier:identifier encodedContentRuleList:[encodedContentRuleList retain] completionHandler:completionHandler];
77 }
78
79 - (void)lookUpContentRuleListForIdentifier:(NSString *)identifier completionHandler:(void (^)(WKContentRuleList *, NSError *))completionHandler
80 {
81     _contentRuleListStore->lookupContentRuleList(identifier, [completionHandler = makeBlockPtr(completionHandler)](RefPtr<API::ContentRuleList> contentRuleList, std::error_code error) {
82         if (error) {
83             auto userInfo = @{NSHelpAnchorErrorKey: [NSString stringWithFormat:@"Rule list lookup failed: %s", error.message().c_str()]};
84             auto wkError = toWKErrorCode(error);
85             ASSERT(wkError == WKErrorContentRuleListStoreLookUpFailed || wkError == WKErrorContentRuleListStoreVersionMismatch);
86             return completionHandler(nil, [NSError errorWithDomain:WKErrorDomain code:wkError userInfo:userInfo]);
87         }
88
89         completionHandler(wrapper(*contentRuleList), nil);
90     });
91 }
92
93 - (void)getAvailableContentRuleListIdentifiers:(void (^)(NSArray<NSString *>*))completionHandler
94 {
95     _contentRuleListStore->getAvailableContentRuleListIdentifiers([completionHandler = makeBlockPtr(completionHandler)](Vector<String> identifiers) {
96         NSMutableArray<NSString *> *nsIdentifiers = [NSMutableArray arrayWithCapacity:identifiers.size()];
97         for (const auto& identifier : identifiers)
98             [nsIdentifiers addObject:identifier];
99         completionHandler(nsIdentifiers);
100     });
101 }
102
103 - (void)removeContentRuleListForIdentifier:(NSString *)identifier completionHandler:(void (^)(NSError *))completionHandler
104 {
105     _contentRuleListStore->removeContentRuleList(identifier, [completionHandler = makeBlockPtr(completionHandler)](std::error_code error) {
106         if (error) {
107             auto userInfo = @{NSHelpAnchorErrorKey: [NSString stringWithFormat:@"Rule list removal failed: %s", error.message().c_str()]};
108             ASSERT(toWKErrorCode(error) == WKErrorContentRuleListStoreRemoveFailed);
109             return completionHandler([NSError errorWithDomain:WKErrorDomain code:WKErrorContentRuleListStoreRemoveFailed userInfo:userInfo]);
110         }
111
112         completionHandler(nil);
113     });
114 }
115
116 #pragma mark WKObject protocol implementation
117
118 - (API::Object&)_apiObject
119 {
120     return *_contentRuleListStore;
121 }
122
123 @end
124
125 @implementation WKContentRuleListStore (WKPrivate)
126
127 // For testing only.
128
129 + (void)_registerPathAsUnsafeToMemoryMapForTesting:(NSString *)filename
130 {
131     WebKit::NetworkCache::registerPathAsUnsafeToMemoryMapForTesting(filename);
132 }
133
134 - (void)_removeAllContentRuleLists
135 {
136     _contentRuleListStore->synchronousRemoveAllContentRuleLists();
137 }
138
139 - (void)_invalidateContentRuleListVersionForIdentifier:(NSString *)identifier
140 {
141     _contentRuleListStore->invalidateContentRuleListVersion(identifier);
142 }
143
144 - (void)_getContentRuleListSourceForIdentifier:(NSString *)identifier completionHandler:(void (^)(NSString*))completionHandler
145 {
146     auto handler = adoptNS([completionHandler copy]);
147     _contentRuleListStore->getContentRuleListSource(identifier, [handler](String source) {
148         auto rawHandler = (void (^)(NSString *))handler.get();
149         if (source.isNull())
150             rawHandler(nil);
151         else
152             rawHandler(source);
153     });
154 }
155
156 // NS_RELEASES_ARGUMENT to keep peak memory usage low.
157 - (void)_compileContentRuleListForIdentifier:(NSString *)identifier encodedContentRuleList:(NSString *) NS_RELEASES_ARGUMENT encodedContentRuleList completionHandler:(void (^)(WKContentRuleList *, NSError *))completionHandler
158 {
159     String json(encodedContentRuleList);
160     [encodedContentRuleList release];
161     encodedContentRuleList = nil;
162
163     _contentRuleListStore->compileContentRuleList(identifier, WTFMove(json), [completionHandler = makeBlockPtr(completionHandler)](RefPtr<API::ContentRuleList> contentRuleList, std::error_code error) {
164         if (error) {
165             auto userInfo = @{NSHelpAnchorErrorKey: [NSString stringWithFormat:@"Rule list compilation failed: %s", error.message().c_str()]};
166
167             // error.value() could have a specific compiler error that is not equal to WKErrorContentRuleListStoreCompileFailed.
168             // We want to use error.message, but here we want to only pass on CompileFailed with userInfo from the std::error_code.
169             return completionHandler(nil, [NSError errorWithDomain:WKErrorDomain code:WKErrorContentRuleListStoreCompileFailed userInfo:userInfo]);
170         }
171         completionHandler(wrapper(*contentRuleList), nil);
172     });
173 }
174
175 + (instancetype)defaultStoreWithLegacyFilename
176 {
177     const bool legacyFilename = true;
178     return wrapper(API::ContentRuleListStore::defaultStore(legacyFilename));
179 }
180
181 + (instancetype)storeWithURLAndLegacyFilename:(NSURL *)url
182 {
183     const bool legacyFilename = true;
184     return wrapper(API::ContentRuleListStore::storeWithPath(url.absoluteURL.fileSystemRepresentation, legacyFilename));
185 }
186
187 @end