Sat, 03 Jan 2015 20:18:00 +0100
Conditionally enable double key logic according to:
private browsing mode or privacy.thirdparty.isolate preference and
implement in GetCookieStringCommon and FindCookie where it counts...
With some reservations of how to convince FindCookie users to test
condition and pass a nullptr when disabling double key logic.
2 /*
3 * Copyright 2006 The Android Open Source Project
4 *
5 * Use of this source code is governed by a BSD-style license that can be
6 * found in the LICENSE file.
7 */
10 #include "SkEventSink.h"
11 #include "SkTagList.h"
12 #include "SkThread.h"
14 #include "SkThread.h"
15 #include "SkTime.h"
17 class SkEventSink_Globals {
18 public:
19 SkEventSink_Globals() {
20 fNextSinkID = 0;
21 fSinkHead = NULL;
22 }
24 SkMutex fSinkMutex;
25 SkEventSinkID fNextSinkID;
26 SkEventSink* fSinkHead;
27 };
29 static SkEventSink_Globals& getGlobals() {
30 // leak this, so we don't incur any shutdown perf hit
31 static SkEventSink_Globals* gGlobals = new SkEventSink_Globals;
32 return *gGlobals;
33 }
35 SkEventSink::SkEventSink() : fTagHead(NULL) {
36 SkEventSink_Globals& globals = getGlobals();
38 globals.fSinkMutex.acquire();
40 fID = ++globals.fNextSinkID;
41 fNextSink = globals.fSinkHead;
42 globals.fSinkHead = this;
44 globals.fSinkMutex.release();
45 }
47 SkEventSink::~SkEventSink() {
48 SkEventSink_Globals& globals = getGlobals();
50 if (fTagHead)
51 SkTagList::DeleteAll(fTagHead);
53 globals.fSinkMutex.acquire();
55 SkEventSink* sink = globals.fSinkHead;
56 SkEventSink* prev = NULL;
58 for (;;) {
59 SkEventSink* next = sink->fNextSink;
60 if (sink == this) {
61 if (prev) {
62 prev->fNextSink = next;
63 } else {
64 globals.fSinkHead = next;
65 }
66 break;
67 }
68 prev = sink;
69 sink = next;
70 }
71 globals.fSinkMutex.release();
72 }
74 bool SkEventSink::doEvent(const SkEvent& evt) {
75 return this->onEvent(evt);
76 }
78 bool SkEventSink::doQuery(SkEvent* evt) {
79 SkASSERT(evt);
80 return this->onQuery(evt);
81 }
83 bool SkEventSink::onEvent(const SkEvent&) {
84 return false;
85 }
87 bool SkEventSink::onQuery(SkEvent*) {
88 return false;
89 }
91 ///////////////////////////////////////////////////////////////////////////////
93 SkTagList* SkEventSink::findTagList(U8CPU tag) const {
94 return fTagHead ? SkTagList::Find(fTagHead, tag) : NULL;
95 }
97 void SkEventSink::addTagList(SkTagList* rec) {
98 SkASSERT(rec);
99 SkASSERT(fTagHead == NULL || SkTagList::Find(fTagHead, rec->fTag) == NULL);
101 rec->fNext = fTagHead;
102 fTagHead = rec;
103 }
105 void SkEventSink::removeTagList(U8CPU tag) {
106 if (fTagHead) {
107 SkTagList::DeleteTag(&fTagHead, tag);
108 }
109 }
111 ///////////////////////////////////////////////////////////////////////////////
113 struct SkListenersTagList : SkTagList {
114 SkListenersTagList(U16CPU count) : SkTagList(kListeners_SkTagList)
115 {
116 fExtra16 = SkToU16(count);
117 fIDs = (SkEventSinkID*)sk_malloc_throw(count * sizeof(SkEventSinkID));
118 }
119 virtual ~SkListenersTagList()
120 {
121 sk_free(fIDs);
122 }
124 int countListners() const { return fExtra16; }
126 int find(SkEventSinkID id) const
127 {
128 const SkEventSinkID* idptr = fIDs;
129 for (int i = fExtra16 - 1; i >= 0; --i)
130 if (idptr[i] == id)
131 return i;
132 return -1;
133 }
135 SkEventSinkID* fIDs;
136 };
138 void SkEventSink::addListenerID(SkEventSinkID id)
139 {
140 if (id == 0)
141 return;
143 SkListenersTagList* prev = (SkListenersTagList*)this->findTagList(kListeners_SkTagList);
144 int count = 0;
146 if (prev)
147 {
148 if (prev->find(id) >= 0)
149 return;
150 count = prev->countListners();
151 }
153 SkListenersTagList* next = SkNEW_ARGS(SkListenersTagList, (count + 1));
155 if (prev)
156 {
157 memcpy(next->fIDs, prev->fIDs, count * sizeof(SkEventSinkID));
158 this->removeTagList(kListeners_SkTagList);
159 }
160 next->fIDs[count] = id;
161 this->addTagList(next);
162 }
164 void SkEventSink::copyListeners(const SkEventSink& sink)
165 {
166 SkListenersTagList* sinkList = (SkListenersTagList*)sink.findTagList(kListeners_SkTagList);
167 if (sinkList == NULL)
168 return;
169 SkASSERT(sinkList->countListners() > 0);
170 const SkEventSinkID* iter = sinkList->fIDs;
171 const SkEventSinkID* stop = iter + sinkList->countListners();
172 while (iter < stop)
173 addListenerID(*iter++);
174 }
176 void SkEventSink::removeListenerID(SkEventSinkID id)
177 {
178 if (id == 0)
179 return;
181 SkListenersTagList* list = (SkListenersTagList*)this->findTagList(kListeners_SkTagList);
183 if (list == NULL)
184 return;
186 int index = list->find(id);
187 if (index >= 0)
188 {
189 int count = list->countListners();
190 SkASSERT(count > 0);
191 if (count == 1)
192 this->removeTagList(kListeners_SkTagList);
193 else
194 {
195 // overwrite without resize/reallocating our struct (for speed)
196 list->fIDs[index] = list->fIDs[count - 1];
197 list->fExtra16 = SkToU16(count - 1);
198 }
199 }
200 }
202 bool SkEventSink::hasListeners() const
203 {
204 return this->findTagList(kListeners_SkTagList) != NULL;
205 }
207 void SkEventSink::postToListeners(const SkEvent& evt, SkMSec delay) {
208 SkListenersTagList* list = (SkListenersTagList*)this->findTagList(kListeners_SkTagList);
209 if (list) {
210 SkASSERT(list->countListners() > 0);
211 const SkEventSinkID* iter = list->fIDs;
212 const SkEventSinkID* stop = iter + list->countListners();
213 while (iter < stop) {
214 SkEvent* copy = SkNEW_ARGS(SkEvent, (evt));
215 copy->setTargetID(*iter++)->postDelay(delay);
216 }
217 }
218 }
220 ///////////////////////////////////////////////////////////////////////////////
222 SkEventSink::EventResult SkEventSink::DoEvent(const SkEvent& evt) {
223 SkEvent::Proc proc = evt.getTargetProc();
224 if (proc) {
225 return proc(evt) ? kHandled_EventResult : kNotHandled_EventResult;
226 }
228 SkEventSink* sink = SkEventSink::FindSink(evt.getTargetID());
229 if (sink) {
230 return sink->doEvent(evt) ? kHandled_EventResult : kNotHandled_EventResult;
231 }
233 return kSinkNotFound_EventResult;
234 }
236 SkEventSink* SkEventSink::FindSink(SkEventSinkID sinkID)
237 {
238 if (sinkID == 0)
239 return 0;
241 SkEventSink_Globals& globals = getGlobals();
242 SkAutoMutexAcquire ac(globals.fSinkMutex);
243 SkEventSink* sink = globals.fSinkHead;
245 while (sink)
246 {
247 if (sink->getSinkID() == sinkID)
248 return sink;
249 sink = sink->fNextSink;
250 }
251 return NULL;
252 }
254 ////////////////////////////////////////////////////////////////////////////////////////
255 ////////////////////////////////////////////////////////////////////////////////////////
257 #if 0 // experimental, not tested
259 #include "SkThread.h"
260 #include "SkTDict.h"
262 #define kMinStringBufferSize 128
263 SK_DECLARE_STATIC_MUTEX(gNamedSinkMutex);
264 static SkTDict<SkEventSinkID> gNamedSinkIDs(kMinStringBufferSize);
266 /** Register a name/id pair with the system. If the name already exists,
267 replace its ID with the new id. This pair will persist until UnregisterNamedSink()
268 is called.
269 */
270 void SkEventSink::RegisterNamedSinkID(const char name[], SkEventSinkID id)
271 {
272 if (id && name && *name)
273 {
274 SkAutoMutexAcquire ac(gNamedSinkMutex);
275 gNamedSinkIDs.set(name, id);
276 }
277 }
279 /** Return the id that matches the specified name (from a previous call to
280 RegisterNamedSinkID(). If no match is found, return 0
281 */
282 SkEventSinkID SkEventSink::FindNamedSinkID(const char name[])
283 {
284 SkEventSinkID id = 0;
286 if (name && *name)
287 {
288 SkAutoMutexAcquire ac(gNamedSinkMutex);
289 (void)gNamedSinkIDs.find(name, &id);
290 }
291 return id;
292 }
294 /** Remove all name/id pairs from the system. This is call internally
295 on shutdown, to ensure no memory leaks. It should not be called
296 before shutdown.
297 */
298 void SkEventSink::RemoveAllNamedSinkIDs()
299 {
300 SkAutoMutexAcquire ac(gNamedSinkMutex);
301 (void)gNamedSinkIDs.reset();
302 }
303 #endif