Unreviewed, rolling out r223889.
[WebKit-https.git] / Source / WebKit / Shared / ios / InteractionInformationAtPosition.mm
1 /*
2  * Copyright (C) 2014 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 "InteractionInformationAtPosition.h"
28
29 #import "ArgumentCodersCF.h"
30 #import "WebCoreArgumentCoders.h"
31 #import <pal/spi/cocoa/DataDetectorsCoreSPI.h>
32 #import <wtf/SoftLinking.h>
33
34 SOFT_LINK_PRIVATE_FRAMEWORK(DataDetectorsCore)
35 SOFT_LINK_CLASS(DataDetectorsCore, DDScannerResult)
36
37 namespace WebKit {
38
39 #if PLATFORM(IOS)
40
41 void InteractionInformationAtPosition::encode(IPC::Encoder& encoder) const
42 {
43     encoder << request;
44
45     encoder << nodeAtPositionIsAssistedNode;
46 #if ENABLE(DATA_INTERACTION)
47     encoder << hasSelectionAtPosition;
48 #endif
49     encoder << isSelectable;
50     encoder << isNearMarkedText;
51     encoder << touchCalloutEnabled;
52     encoder << isLink;
53     encoder << isImage;
54     encoder << isAttachment;
55     encoder << isAnimatedImage;
56     encoder << isElement;
57     encoder << adjustedPointForNodeRespondingToClickEvents;
58     encoder << url;
59     encoder << imageURL;
60     encoder << title;
61     encoder << idAttribute;
62     encoder << bounds;
63     encoder << textBefore;
64     encoder << textAfter;
65     encoder << linkIndicator;
66
67     ShareableBitmap::Handle handle;
68     if (image)
69         image->createHandle(handle, SharedMemory::Protection::ReadOnly);
70     encoder << handle;
71 #if ENABLE(DATA_DETECTION)
72     encoder << isDataDetectorLink;
73     if (isDataDetectorLink) {
74         encoder << dataDetectorIdentifier;
75         RetainPtr<NSMutableData> data = adoptNS([[NSMutableData alloc] init]);
76         RetainPtr<NSKeyedArchiver> archiver = adoptNS([[NSKeyedArchiver alloc] initForWritingWithMutableData:data.get()]);
77         [archiver setRequiresSecureCoding:YES];
78         [archiver encodeObject:dataDetectorResults.get() forKey:@"dataDetectorResults"];
79         [archiver finishEncoding];
80         
81         IPC::encode(encoder, reinterpret_cast<CFDataRef>(data.get()));        
82     }
83 #endif
84 }
85
86 bool InteractionInformationAtPosition::decode(IPC::Decoder& decoder, InteractionInformationAtPosition& result)
87 {
88     if (!decoder.decode(result.request))
89         return false;
90
91     if (!decoder.decode(result.nodeAtPositionIsAssistedNode))
92         return false;
93
94 #if ENABLE(DATA_INTERACTION)
95     if (!decoder.decode(result.hasSelectionAtPosition))
96         return false;
97 #endif
98
99     if (!decoder.decode(result.isSelectable))
100         return false;
101
102     if (!decoder.decode(result.isNearMarkedText))
103         return false;
104
105     if (!decoder.decode(result.touchCalloutEnabled))
106         return false;
107
108     if (!decoder.decode(result.isLink))
109         return false;
110
111     if (!decoder.decode(result.isImage))
112         return false;
113
114     if (!decoder.decode(result.isAttachment))
115         return false;
116     
117     if (!decoder.decode(result.isAnimatedImage))
118         return false;
119     
120     if (!decoder.decode(result.isElement))
121         return false;
122
123     if (!decoder.decode(result.adjustedPointForNodeRespondingToClickEvents))
124         return false;
125
126     if (!decoder.decode(result.url))
127         return false;
128
129     if (!decoder.decode(result.imageURL))
130         return false;
131
132     if (!decoder.decode(result.title))
133         return false;
134
135     if (!decoder.decode(result.idAttribute))
136         return false;
137     
138     if (!decoder.decode(result.bounds))
139         return false;
140
141     if (!decoder.decode(result.textBefore))
142         return false;
143     
144     if (!decoder.decode(result.textAfter))
145         return false;
146     
147     std::optional<WebCore::TextIndicatorData> linkIndicator;
148     decoder >> linkIndicator;
149     if (!linkIndicator)
150         return false;
151     result.linkIndicator = WTFMove(*linkIndicator);
152
153     ShareableBitmap::Handle handle;
154     if (!decoder.decode(handle))
155         return false;
156
157     if (!handle.isNull())
158         result.image = ShareableBitmap::create(handle, SharedMemory::Protection::ReadOnly);
159
160 #if ENABLE(DATA_DETECTION)
161     if (!decoder.decode(result.isDataDetectorLink))
162         return false;
163     
164     if (result.isDataDetectorLink) {
165         if (!decoder.decode(result.dataDetectorIdentifier))
166             return false;
167         RetainPtr<CFDataRef> data;
168         if (!IPC::decode(decoder, data))
169             return false;
170         
171         RetainPtr<NSKeyedUnarchiver> unarchiver = adoptNS([[NSKeyedUnarchiver alloc] initForReadingWithData:(NSData *)data.get()]);
172         [unarchiver setRequiresSecureCoding:YES];
173         @try {
174             result.dataDetectorResults = [unarchiver decodeObjectOfClasses:[NSSet setWithArray:@[ [NSArray class], getDDScannerResultClass()] ] forKey:@"dataDetectorResults"];
175         } @catch (NSException *exception) {
176             LOG_ERROR("Failed to decode NSArray of DDScanResult: %@", exception);
177             return false;
178         }
179         
180         [unarchiver finishDecoding];
181     }
182 #endif
183
184     return true;
185 }
186
187 void InteractionInformationAtPosition::mergeCompatibleOptionalInformation(const InteractionInformationAtPosition& oldInformation)
188 {
189     if (oldInformation.request.point != request.point)
190         return;
191
192     if (oldInformation.request.includeSnapshot && !request.includeSnapshot)
193         image = oldInformation.image;
194
195     if (oldInformation.request.includeLinkIndicator && !request.includeLinkIndicator)
196         linkIndicator = oldInformation.linkIndicator;
197 }
198
199 #endif // PLATFORM(IOS)
200
201 }